Skip to content

Commit 9ac222e

Browse files
committed
Implement update checking feature with UI and service integration
1 parent 2ac9376 commit 9ac222e

File tree

6 files changed

+247
-5
lines changed

6 files changed

+247
-5
lines changed

.github/workflows/release.yml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,13 @@ jobs:
4444

4545
- name: Build Windows executable
4646
run: |
47-
dotnet publish SemanticCode.Desktop/SemanticCode.Desktop.csproj -c Release -r win-x64 --self-contained true -o ./publish/win-x64
47+
dotnet publish SemanticCode.Desktop/SemanticCode.Desktop.csproj -c Release -r win-x64 --self-contained true -o ./publish/win-x64 -p:DebugType=None -p:DebugSymbols=false
4848
49-
- name: Create Windows archive
49+
- name: Remove debug files and create Windows archive
5050
run: |
5151
cd publish/win-x64
52+
# Remove .pdb files if any exist
53+
if ls *.pdb 1> /dev/null 2>&1; then rm *.pdb; fi
5254
7z a ../../SemanticCode-${{ needs.prepare.outputs.version }}-win-x64.zip *
5355
5456
- name: Upload Windows artifact
@@ -74,11 +76,13 @@ jobs:
7476

7577
- name: Build Linux executable
7678
run: |
77-
dotnet publish SemanticCode.Desktop/SemanticCode.Desktop.csproj -c Release -r linux-x64 --self-contained true -o ./publish/linux-x64
79+
dotnet publish SemanticCode.Desktop/SemanticCode.Desktop.csproj -c Release -r linux-x64 --self-contained true -o ./publish/linux-x64 -p:DebugType=None -p:DebugSymbols=false
7880
79-
- name: Create Linux archive
81+
- name: Remove debug files and create Linux archive
8082
run: |
8183
cd publish/linux-x64
84+
# Remove .pdb files if any exist
85+
find . -name "*.pdb" -type f -delete
8286
tar -czf ../../SemanticCode-${{ needs.prepare.outputs.version }}-linux-x64.tar.gz *
8387
8488
- name: Upload Linux artifact

Directory.Packages.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22
<PropertyGroup>
33
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4-
<Version>0.1.1.0</Version>
4+
<Version>0.1.1.1</Version>
55
<AssemblyVersion>$(Version)</AssemblyVersion>
66
<FileVersion>$(Version)</FileVersion>
77
<InformationalVersion>$(Version)</InformationalVersion>

SemanticCode/Models/UpdateInfo.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace SemanticCode.Models;
5+
6+
public class UpdateInfo
7+
{
8+
public string Version { get; set; } = string.Empty;
9+
public string ReleaseUrl { get; set; } = string.Empty;
10+
public string Description { get; set; } = string.Empty;
11+
public DateTime PublishedAt { get; set; }
12+
public bool IsNewerVersion { get; set; }
13+
public List<UpdateAsset> Assets { get; set; } = new();
14+
}
15+
16+
public class UpdateAsset
17+
{
18+
public string Name { get; set; } = string.Empty;
19+
public string DownloadUrl { get; set; } = string.Empty;
20+
public long Size { get; set; }
21+
}

SemanticCode/Pages/SystemSettingsView.axaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,56 @@
9292
VerticalAlignment="Center"/>
9393
</Grid>
9494
</Border>
95+
96+
<Border Background="{DynamicResource CardBackgroundFillColorDefaultBrush}"
97+
BorderBrush="{DynamicResource CardStrokeColorDefaultBrush}"
98+
BorderThickness="1"
99+
CornerRadius="8"
100+
Padding="16">
101+
<StackPanel Spacing="12">
102+
<TextBlock Text="{Binding UpdateLabel}"
103+
FontWeight="SemiBold"
104+
FontSize="16"/>
105+
<TextBlock Text="检查应用程序更新"
106+
Opacity="0.8"
107+
FontSize="14"/>
108+
<Grid ColumnDefinitions="*,Auto">
109+
<TextBlock Grid.Column="0"
110+
Text="{Binding UpdateStatus}"
111+
VerticalAlignment="Center"
112+
FontSize="14"/>
113+
<Button Grid.Column="1"
114+
Content="检查更新"
115+
Command="{Binding CheckUpdateCommand}"
116+
IsEnabled="{Binding !IsCheckingUpdate}"
117+
MinWidth="100"/>
118+
</Grid>
119+
120+
<!-- Update details when available -->
121+
<Border IsVisible="{Binding LatestUpdate.IsNewerVersion}"
122+
Background="{DynamicResource AccentFillColorDefaultBrush}"
123+
CornerRadius="4"
124+
Padding="12"
125+
Margin="0,8,0,0">
126+
<StackPanel Spacing="8">
127+
<TextBlock Text="{Binding LatestUpdate.Version, StringFormat='新版本: v{0}'}"
128+
FontWeight="SemiBold"
129+
Foreground="White"/>
130+
<TextBlock Text="{Binding LatestUpdate.Description}"
131+
Foreground="White"
132+
TextWrapping="Wrap"
133+
MaxHeight="100"
134+
IsVisible="{Binding LatestUpdate.Description, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
135+
<Button Content="查看发布页面"
136+
Background="Transparent"
137+
BorderBrush="White"
138+
Foreground="White"
139+
HorizontalAlignment="Left"
140+
Margin="0,4,0,0"/>
141+
</StackPanel>
142+
</Border>
143+
</StackPanel>
144+
</Border>
95145
</StackPanel>
96146
</ScrollViewer>
97147
</UserControl>
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using System;
2+
using System.Net.Http;
3+
using System.Text.Json;
4+
using System.Reflection;
5+
using System.Threading.Tasks;
6+
using SemanticCode.Models;
7+
8+
namespace SemanticCode.Services;
9+
10+
public class UpdateService
11+
{
12+
private readonly HttpClient _httpClient;
13+
private const string GitHubApiUrl = "https://api.github.com/repos/AIDotNet/SemanticCode/releases/latest";
14+
15+
public UpdateService()
16+
{
17+
_httpClient = new HttpClient();
18+
_httpClient.DefaultRequestHeaders.Add("User-Agent", "SemanticCode-UpdateChecker");
19+
}
20+
21+
public async Task<UpdateInfo?> CheckForUpdatesAsync()
22+
{
23+
try
24+
{
25+
var response = await _httpClient.GetStringAsync(GitHubApiUrl);
26+
var releaseData = JsonSerializer.Deserialize<JsonElement>(response);
27+
28+
var latestVersion = releaseData.GetProperty("tag_name").GetString()?.TrimStart('v');
29+
var currentVersion = GetCurrentVersion();
30+
31+
if (string.IsNullOrEmpty(latestVersion) || string.IsNullOrEmpty(currentVersion))
32+
return null;
33+
34+
var updateInfo = new UpdateInfo
35+
{
36+
Version = latestVersion,
37+
ReleaseUrl = releaseData.GetProperty("html_url").GetString() ?? "",
38+
Description = releaseData.GetProperty("body").GetString() ?? "",
39+
PublishedAt = releaseData.GetProperty("published_at").GetDateTime(),
40+
IsNewerVersion = IsNewerVersion(currentVersion, latestVersion)
41+
};
42+
43+
if (releaseData.TryGetProperty("assets", out var assetsElement))
44+
{
45+
foreach (var asset in assetsElement.EnumerateArray())
46+
{
47+
updateInfo.Assets.Add(new UpdateAsset
48+
{
49+
Name = asset.GetProperty("name").GetString() ?? "",
50+
DownloadUrl = asset.GetProperty("browser_download_url").GetString() ?? "",
51+
Size = asset.GetProperty("size").GetInt64()
52+
});
53+
}
54+
}
55+
56+
return updateInfo;
57+
}
58+
catch (Exception)
59+
{
60+
return null;
61+
}
62+
}
63+
64+
private string GetCurrentVersion()
65+
{
66+
var assembly = Assembly.GetExecutingAssembly();
67+
var version = assembly.GetName().Version;
68+
return version?.ToString() ?? "0.0.0.0";
69+
}
70+
71+
private bool IsNewerVersion(string currentVersion, string latestVersion)
72+
{
73+
if (Version.TryParse(currentVersion, out var current) &&
74+
Version.TryParse(latestVersion, out var latest))
75+
{
76+
return latest > current;
77+
}
78+
79+
return false;
80+
}
81+
82+
public void Dispose()
83+
{
84+
_httpClient.Dispose();
85+
}
86+
}

SemanticCode/ViewModels/SystemSettingsViewModel.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
using System;
12
using System.Collections.Generic;
3+
using System.Reactive;
4+
using System.Threading.Tasks;
5+
using System.Windows.Input;
26
using ReactiveUI;
7+
using SemanticCode.Services;
8+
using SemanticCode.Models;
39

410
namespace SemanticCode.ViewModels;
511

@@ -52,4 +58,79 @@ public bool EnableNotifications
5258
"English",
5359
"日本語"
5460
};
61+
62+
private readonly UpdateService _updateService;
63+
64+
public SystemSettingsViewModel()
65+
{
66+
_updateService = new UpdateService();
67+
CheckUpdateCommand = ReactiveCommand.CreateFromTask(CheckForUpdatesAsync);
68+
69+
// 当进入系统设置页面时自动检查更新
70+
_ = Task.Run(async () =>
71+
{
72+
await Task.Delay(1000); // 延迟1秒后自动检查
73+
await CheckForUpdatesAsync();
74+
});
75+
}
76+
77+
public string UpdateLabel { get; } = "更新检查";
78+
public ReactiveCommand<Unit, Unit> CheckUpdateCommand { get; }
79+
80+
private bool _isCheckingUpdate = false;
81+
public bool IsCheckingUpdate
82+
{
83+
get => _isCheckingUpdate;
84+
set => this.RaiseAndSetIfChanged(ref _isCheckingUpdate, value);
85+
}
86+
87+
private string _updateStatus = "点击检查更新";
88+
public string UpdateStatus
89+
{
90+
get => _updateStatus;
91+
set => this.RaiseAndSetIfChanged(ref _updateStatus, value);
92+
}
93+
94+
private UpdateInfo? _latestUpdate;
95+
public UpdateInfo? LatestUpdate
96+
{
97+
get => _latestUpdate;
98+
set => this.RaiseAndSetIfChanged(ref _latestUpdate, value);
99+
}
100+
101+
private async Task CheckForUpdatesAsync()
102+
{
103+
IsCheckingUpdate = true;
104+
UpdateStatus = "正在检查更新...";
105+
106+
try
107+
{
108+
var updateInfo = await _updateService.CheckForUpdatesAsync();
109+
110+
if (updateInfo == null)
111+
{
112+
UpdateStatus = "检查更新失败";
113+
return;
114+
}
115+
116+
LatestUpdate = updateInfo;
117+
118+
if (updateInfo.IsNewerVersion)
119+
{
120+
UpdateStatus = $"发现新版本 v{updateInfo.Version}";
121+
}
122+
else
123+
{
124+
UpdateStatus = "已是最新版本";
125+
}
126+
}
127+
catch (Exception)
128+
{
129+
UpdateStatus = "检查更新失败";
130+
}
131+
finally
132+
{
133+
IsCheckingUpdate = false;
134+
}
135+
}
55136
}

0 commit comments

Comments
 (0)