Skip to content

Commit d64927f

Browse files
committed
feat: Add original text preservation and configurable export separator
- Preserve original proxy line during parsing - Add option to export original line - Add custom export separator configuration - Fix ExportOptionsDialog layout and interaction - Fix potential null dereference in CopyAsync
1 parent ebef214 commit d64927f

5 files changed

Lines changed: 43 additions & 17 deletions

File tree

Dialogs/Models/ExportOptionsModel.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
using CommunityToolkit.Mvvm.ComponentModel;
33
using Irihi.Avalonia.Shared.Contracts;
44

5+
using Ursa.Common;
6+
using Ursa.Controls;
7+
58
namespace ProxyChecker.Dialogs.Models;
69

710
public partial class ExportOptionsModel : ObservableObject, IDialogContext
@@ -14,6 +17,8 @@ public partial class ExportOptionsModel : ObservableObject, IDialogContext
1417
[ObservableProperty] private bool _includeLocation = false;
1518
[ObservableProperty] private bool _includeIsp = false;
1619
[ObservableProperty] private bool _includeResponseTime = false;
20+
[ObservableProperty] private bool _includeOriginalLine = false;
21+
[ObservableProperty] private string _separator = ",";
1722
[ObservableProperty] private bool _onlySuccess = true;
1823

1924
public void Close()
@@ -23,8 +28,8 @@ public void Close()
2328

2429
public event EventHandler<object?>? RequestClose;
2530

26-
public void Confirm() => RequestClose?.Invoke(this, true);
27-
public void Cancel() => RequestClose?.Invoke(this, false);
31+
public void Confirm() => RequestClose?.Invoke(this, DialogResult.OK);
32+
public void Cancel() => RequestClose?.Invoke(this, DialogResult.Cancel);
2833

2934
// 全选所有字段
3035
public void SelectAll()
@@ -37,6 +42,7 @@ public void SelectAll()
3742
IncludeLocation = true;
3843
IncludeIsp = true;
3944
IncludeResponseTime = true;
45+
IncludeOriginalLine = true;
4046
}
4147

4248
// 取消全选
@@ -50,5 +56,6 @@ public void DeselectAll()
5056
IncludeLocation = false;
5157
IncludeIsp = false;
5258
IncludeResponseTime = false;
59+
IncludeOriginalLine = false;
5360
}
5461
}

Dialogs/Views/ExportOptionsDialog.axaml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,12 @@
3030
CornerRadius="6" Padding="12" Margin="0,0,0,8">
3131
<StackPanel Spacing="8">
3232
<TextBlock Text="代理信息" Foreground="{DynamicResource SemiColorText2}" FontWeight="Bold"/>
33-
<UniformGrid Columns="2" Rows="2">
33+
<UniformGrid Columns="2">
3434
<CheckBox Content="IP" IsChecked="{Binding IncludeIp}" Margin="0,4"/>
3535
<CheckBox Content="端口" IsChecked="{Binding IncludePort}" Margin="0,4"/>
3636
<CheckBox Content="用户名" IsChecked="{Binding IncludeUsername}" Margin="0,4"/>
3737
<CheckBox Content="密码" IsChecked="{Binding IncludePassword}" Margin="0,4"/>
38+
<CheckBox Content="原始行" IsChecked="{Binding IncludeOriginalLine}" Margin="0,4"/>
3839
</UniformGrid>
3940
</StackPanel>
4041
</Border>
@@ -57,16 +58,21 @@
5758

5859
<u:Divider Margin="0,4"/>
5960

60-
<Grid ColumnDefinitions="Auto,*" Margin="0,4">
61+
<Grid ColumnDefinitions="Auto,*,Auto" Margin="0,4">
6162
<CheckBox Grid.Column="0" Content="仅导出成功的代理" IsChecked="{Binding OnlySuccess}"
6263
FontWeight="Bold"
6364
VerticalAlignment="Center"/>
6465

65-
<StackPanel Grid.Column="1" Orientation="Horizontal" Spacing="12" HorizontalAlignment="Right">
66-
<Button Content="取消" Command="{Binding Cancel}" Classes="Tertiary" Width="80"/>
67-
<Button Content="确定" Command="{Binding Confirm}" Classes="Primary" Theme="{DynamicResource SolidButton}" Width="80"/>
66+
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="8">
67+
<TextBlock Text="分隔符" VerticalAlignment="Center"/>
68+
<TextBox Text="{Binding Separator}" Width="60" TextAlignment="Center"/>
6869
</StackPanel>
6970
</Grid>
71+
72+
<StackPanel Orientation="Horizontal" Spacing="12" HorizontalAlignment="Right" Margin="0,8,0,0">
73+
<Button Content="取消" Command="{Binding Cancel}" Classes="Tertiary" Width="80"/>
74+
<Button Content="确定" Command="{Binding Confirm}" Classes="Primary" Theme="{DynamicResource SolidButton}" Width="80"/>
75+
</StackPanel>
7076
</StackPanel>
7177
</Border>
7278
</UserControl>

Models/ProxyInfo.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ public record ProxyInfo(
55
string Ip,
66
int Port,
77
string Username,
8-
string Password = ""
8+
string Password = "",
9+
string OriginalLine = ""
910
)
1011
{
1112
public string Address => $"{Ip}:{Port}";

Services/ProxyFileParser.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ public static List<ProxyInfo> ParseFromContent(string content)
122122
Ip: subIp,
123123
Port: subPort,
124124
Username: subUser ?? "",
125-
Password: subPass ?? ""
125+
Password: subPass ?? "",
126+
OriginalLine: line
126127
);
127128
}
128129
}
@@ -161,7 +162,8 @@ public static List<ProxyInfo> ParseFromContent(string content)
161162
Ip: ip,
162163
Port: port,
163164
Username: username ?? "",
164-
Password: password ?? ""
165+
Password: password ?? "",
166+
OriginalLine: line
165167
);
166168
}
167169
}
@@ -184,7 +186,8 @@ public static List<ProxyInfo> ParseFromContent(string content)
184186
Index: int.Parse(match1.Groups[1].Value),
185187
Ip: match1.Groups[2].Value,
186188
Port: int.Parse(match1.Groups[3].Value),
187-
Username: match1.Groups[4].Value
189+
Username: match1.Groups[4].Value,
190+
OriginalLine: line
188191
);
189192
}
190193

@@ -197,7 +200,8 @@ public static List<ProxyInfo> ParseFromContent(string content)
197200
Ip: match2.Groups[1].Value,
198201
Port: int.Parse(match2.Groups[2].Value),
199202
Username: match2.Groups[3].Value,
200-
Password: match2.Groups[4].Value
203+
Password: match2.Groups[4].Value,
204+
OriginalLine: line
201205
);
202206
}
203207

@@ -209,7 +213,8 @@ public static List<ProxyInfo> ParseFromContent(string content)
209213
Index: defaultIndex,
210214
Ip: match3.Groups[1].Value,
211215
Port: int.Parse(match3.Groups[2].Value),
212-
Username: match3.Groups[3].Value
216+
Username: match3.Groups[3].Value,
217+
OriginalLine: line
213218
);
214219
}
215220

@@ -221,7 +226,8 @@ public static List<ProxyInfo> ParseFromContent(string content)
221226
Index: defaultIndex,
222227
Ip: match4.Groups[1].Value,
223228
Port: int.Parse(match4.Groups[2].Value),
224-
Username: match4.Groups[3].Value
229+
Username: match4.Groups[3].Value,
230+
OriginalLine: line
225231
);
226232
}
227233

ViewModels/MainViewModel.cs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,11 @@ private async Task ExportAllAsync()
575575
{
576576
var parts = new List<string>();
577577

578+
if (optionsModel.IncludeOriginalLine && !string.IsNullOrEmpty(r.Proxy.OriginalLine))
579+
{
580+
parts.Add(r.Proxy.OriginalLine);
581+
}
582+
578583
if (optionsModel.IncludeIp) parts.Add(r.Proxy.Ip);
579584
if (optionsModel.IncludePort) parts.Add(r.Proxy.Port.ToString());
580585
if (optionsModel.IncludeUsername) parts.Add(r.Proxy.Username ?? "");
@@ -584,7 +589,7 @@ private async Task ExportAllAsync()
584589
if (optionsModel.IncludeIsp) parts.Add(r.Isp ?? "");
585590
if (optionsModel.IncludeResponseTime) parts.Add(r.ResponseTimeDisplay);
586591

587-
return string.Join(",", parts);
592+
return string.Join(optionsModel.Separator, parts);
588593
}).ToList();
589594

590595
if (lines.Count == 0) return;
@@ -751,8 +756,9 @@ private async Task CopyAsync()
751756
var selection = ResultsSource.Selection as ITreeDataGridRowSelectionModel<CheckResult>;
752757
if (selection == null || selection.SelectedItems.Count == 0) return;
753758

754-
var text = string.Join(Environment.NewLine, selection.SelectedItems.Select(r =>
755-
string.IsNullOrEmpty(r.Proxy.Username)
759+
var text = string.Join(Environment.NewLine, selection.SelectedItems
760+
.Where(r => r != null)
761+
.Select(r => string.IsNullOrEmpty(r!.Proxy.Username)
756762
? $"{r.Proxy.Ip}:{r.Proxy.Port}"
757763
: $"{r.Proxy.Ip}:{r.Proxy.Port}:{r.Proxy.Username}:{r.Proxy.Password}"));
758764

0 commit comments

Comments
 (0)