Skip to content

Commit 6f16791

Browse files
committed
feature: supports to switch between HTTPS and SSH protocol (#1734)
Signed-off-by: leo <longshuang@msn.cn>
1 parent 668439a commit 6f16791

File tree

5 files changed

+181
-5
lines changed

5 files changed

+181
-5
lines changed

src/Views/AddRemote.axaml

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,14 @@
2929
VerticalAlignment="Center"
3030
CornerRadius="2"
3131
Watermark="{DynamicResource Text.Remote.Name.Placeholder}"
32-
Text="{Binding Name, Mode=TwoWay}"/>
32+
Text="{Binding Name, Mode=TwoWay}">
33+
<TextBox.InnerLeftContent>
34+
<Path Width="12" Height="12"
35+
Margin="4,0,2,0"
36+
Data="{StaticResource Icons.Remote}"
37+
Fill="{DynamicResource Brush.FG1}"/>
38+
</TextBox.InnerLeftContent>
39+
</TextBox>
3340

3441
<TextBlock Grid.Row="1" Grid.Column="0"
3542
HorizontalAlignment="Right" VerticalAlignment="Center"
@@ -40,7 +47,18 @@
4047
VerticalAlignment="Center"
4148
CornerRadius="2"
4249
Watermark="{DynamicResource Text.Remote.URL.Placeholder}"
43-
Text="{Binding Url, Mode=TwoWay}"/>
50+
Text="{Binding Url, Mode=TwoWay}">
51+
<TextBox.InnerLeftContent>
52+
<Path Width="12" Height="12"
53+
Margin="4,0,2,0"
54+
Data="{StaticResource Icons.Link}"
55+
Fill="{DynamicResource Brush.FG1}"/>
56+
</TextBox.InnerLeftContent>
57+
58+
<TextBox.InnerRightContent>
59+
<v:RemoteProtocolSwitcher Url="{Binding Url, Mode=TwoWay}"/>
60+
</TextBox.InnerRightContent>
61+
</TextBox>
4462

4563
<TextBlock Grid.Row="2" Grid.Column="0"
4664
HorizontalAlignment="Right" VerticalAlignment="Center"
@@ -54,6 +72,12 @@
5472
CornerRadius="3"
5573
Watermark="{DynamicResource Text.SSHKey.Placeholder}"
5674
Text="{Binding SSHKey, Mode=TwoWay}">
75+
<TextBox.InnerLeftContent>
76+
<Path Width="12" Height="12"
77+
Margin="4,0,2,0"
78+
Data="{StaticResource Icons.Password}"
79+
Fill="{DynamicResource Brush.FG1}"/>
80+
</TextBox.InnerLeftContent>
5781
<TextBox.InnerRightContent>
5882
<Button Classes="icon_button" Width="30" Height="30" Click="SelectSSHKey">
5983
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>

src/Views/Clone.axaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:vm="using:SourceGit.ViewModels"
6+
xmlns:v="using:SourceGit.Views"
67
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
78
x:Class="SourceGit.Views.Clone"
89
x:DataType="vm:Clone">
@@ -26,7 +27,11 @@
2627
<TextBox Grid.Row="0" Grid.Column="1"
2728
Height="28"
2829
CornerRadius="3"
29-
Text="{Binding Remote, Mode=TwoWay}"/>
30+
Text="{Binding Remote, Mode=TwoWay}">
31+
<TextBox.InnerRightContent>
32+
<v:RemoteProtocolSwitcher Url="{Binding Remote, Mode=TwoWay}"/>
33+
</TextBox.InnerRightContent>
34+
</TextBox>
3035

3136
<TextBlock Grid.Row="1" Grid.Column="0"
3237
HorizontalAlignment="Right"

src/Views/EditRemote.axaml

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
44
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55
xmlns:vm="using:SourceGit.ViewModels"
6+
xmlns:v="using:SourceGit.Views"
67
mc:Ignorable="d" d:DesignWidth="500" d:DesignHeight="450"
78
x:Class="SourceGit.Views.EditRemote"
89
x:DataType="vm:EditRemote">
@@ -27,7 +28,14 @@
2728
VerticalAlignment="Center"
2829
CornerRadius="2"
2930
Watermark="{DynamicResource Text.Remote.Name.Placeholder}"
30-
Text="{Binding Name, Mode=TwoWay}"/>
31+
Text="{Binding Name, Mode=TwoWay}">
32+
<TextBox.InnerLeftContent>
33+
<Path Width="12" Height="12"
34+
Margin="4,0,2,0"
35+
Data="{StaticResource Icons.Remote}"
36+
Fill="{DynamicResource Brush.FG1}"/>
37+
</TextBox.InnerLeftContent>
38+
</TextBox>
3139

3240
<TextBlock Grid.Row="1" Grid.Column="0"
3341
HorizontalAlignment="Right" VerticalAlignment="Center"
@@ -38,7 +46,18 @@
3846
VerticalAlignment="Center"
3947
CornerRadius="2"
4048
Watermark="{DynamicResource Text.Remote.URL.Placeholder}"
41-
Text="{Binding Url, Mode=TwoWay}"/>
49+
Text="{Binding Url, Mode=TwoWay}">
50+
<TextBox.InnerLeftContent>
51+
<Path Width="12" Height="12"
52+
Margin="4,0,2,0"
53+
Data="{StaticResource Icons.Link}"
54+
Fill="{DynamicResource Brush.FG1}"/>
55+
</TextBox.InnerLeftContent>
56+
57+
<TextBox.InnerRightContent>
58+
<v:RemoteProtocolSwitcher Url="{Binding Url, Mode=TwoWay}"/>
59+
</TextBox.InnerRightContent>
60+
</TextBox>
4261

4362
<TextBlock Grid.Row="2" Grid.Column="0"
4463
HorizontalAlignment="Right" VerticalAlignment="Center"
@@ -52,6 +71,12 @@
5271
CornerRadius="3"
5372
Watermark="{DynamicResource Text.SSHKey.Placeholder}"
5473
Text="{Binding SSHKey, Mode=TwoWay}">
74+
<TextBox.InnerLeftContent>
75+
<Path Width="12" Height="12"
76+
Margin="4,0,2,0"
77+
Data="{StaticResource Icons.Password}"
78+
Fill="{DynamicResource Brush.FG1}"/>
79+
</TextBox.InnerLeftContent>
5580
<TextBox.InnerRightContent>
5681
<Button Classes="icon_button" Width="30" Height="30" Click="SelectSSHKey">
5782
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<UserControl xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
6+
x:Class="SourceGit.Views.RemoteProtocolSwitcher"
7+
x:Name="ThisControl">
8+
<Button Classes="icon_button" Click="OnOpenDropdownMenu">
9+
<StackPanel Orientation="Horizontal">
10+
<TextBlock FontSize="12"
11+
Text="{Binding #ThisControl.ActiveProtocol, Mode=OneWay}"
12+
Foreground="{DynamicResource Brush.Link}"/>
13+
<Path Width="10" Height="10"
14+
Margin="4,0,0,0"
15+
VerticalAlignment="Center"
16+
Data="M0 0M1939 486L2029 576L1024 1581L19 576L109 486L1024 1401L1939 486Z"
17+
Fill="{DynamicResource Brush.Link}"/>
18+
</StackPanel>
19+
</Button>
20+
</UserControl>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text.RegularExpressions;
4+
5+
using Avalonia;
6+
using Avalonia.Controls;
7+
using Avalonia.Interactivity;
8+
9+
namespace SourceGit.Views
10+
{
11+
public partial class RemoteProtocolSwitcher : UserControl
12+
{
13+
public static readonly StyledProperty<string> UrlProperty =
14+
AvaloniaProperty.Register<RemoteProtocolSwitcher, string>(nameof(Url));
15+
16+
public string Url
17+
{
18+
get => GetValue(UrlProperty);
19+
set => SetValue(UrlProperty, value);
20+
}
21+
22+
public static readonly StyledProperty<string> ActiveProtocolProperty =
23+
AvaloniaProperty.Register<RemoteProtocolSwitcher, string>(nameof(ActiveProtocol));
24+
25+
public string ActiveProtocol
26+
{
27+
get => GetValue(ActiveProtocolProperty);
28+
set => SetValue(ActiveProtocolProperty, value);
29+
}
30+
31+
public RemoteProtocolSwitcher()
32+
{
33+
InitializeComponent();
34+
}
35+
36+
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
37+
{
38+
base.OnPropertyChanged(change);
39+
40+
if (change.Property == UrlProperty)
41+
{
42+
_protocols.Clear();
43+
44+
var url = Url ?? string.Empty;
45+
if (url.StartsWith("https://", StringComparison.Ordinal) && Uri.TryCreate(url, UriKind.Absolute, out var uri))
46+
{
47+
var host = uri.Host;
48+
var serverName = uri.Port == 443 ? host : $"{host}:{uri.Port}";
49+
var route = uri.AbsolutePath.TrimStart('/');
50+
51+
_protocols.Add(url);
52+
_protocols.Add($"git@{serverName}:{route}");
53+
54+
SetCurrentValue(ActiveProtocolProperty, "HTTPS");
55+
SetCurrentValue(IsVisibleProperty, true);
56+
return;
57+
}
58+
59+
var match = REG_SSH_FORMAT().Match(url);
60+
if (match.Success)
61+
{
62+
var host = match.Groups[1].Value;
63+
var repo = match.Groups[2].Value;
64+
65+
_protocols.Add($"https://{host}/{repo}");
66+
_protocols.Add(url);
67+
68+
SetCurrentValue(ActiveProtocolProperty, "SSH");
69+
SetCurrentValue(IsVisibleProperty, true);
70+
return;
71+
}
72+
73+
SetCurrentValue(IsVisibleProperty, false);
74+
}
75+
}
76+
77+
private void OnOpenDropdownMenu(object sender, RoutedEventArgs e)
78+
{
79+
if (sender is Button btn && _protocols.Count > 0)
80+
{
81+
var menu = new ContextMenu();
82+
menu.Placement = PlacementMode.BottomEdgeAlignedLeft;
83+
84+
foreach (var protocol in _protocols)
85+
{
86+
var dup = protocol;
87+
var item = new MenuItem() { Header = dup };
88+
item.Click += (_, _) => Url = protocol;
89+
menu.Items.Add(item);
90+
}
91+
92+
menu.Open(btn);
93+
}
94+
95+
e.Handled = true;
96+
}
97+
98+
[GeneratedRegex(@"^git@([\w\.\-]+):(.+)$")]
99+
private static partial Regex REG_SSH_FORMAT();
100+
private List<string> _protocols = [];
101+
}
102+
}

0 commit comments

Comments
 (0)