Forge
csharpdeeb25a2
1using System.Collections.ObjectModel;
2using Avalonia.Threading;
3using CommunityToolkit.Mvvm.ComponentModel;
4using CommunityToolkit.Mvvm.Input;
5
6namespace CascadeIDE.ViewModels;
7
8public partial class InstallModelDialogViewModel : ViewModelBase
9{
10 private readonly Services.IOllamaService _ollama;
11 private readonly Action _closeRequested;
12
13 public InstallModelDialogViewModel(Services.IOllamaService ollama, Action closeRequested)
14 {
15 _ollama = ollama;
16 _closeRequested = closeRequested;
17 var recommended = Services.MachineInfo.GetRecommendedModels();
18 RecommendedModels.Clear();
19 foreach (var r in recommended)
20 RecommendedModels.Add(r);
21 }
22
23 public ObservableCollection<Models.RecommendedModel> RecommendedModels { get; } = [];
24
25 [ObservableProperty]
26 [NotifyCanExecuteChangedFor(nameof(InstallCommand))]
27 private Models.RecommendedModel? _selectedRecommended;
28
29 [ObservableProperty]
30 [NotifyCanExecuteChangedFor(nameof(InstallCommand))]
31 private string _customModelName = "";
32
33 [ObservableProperty]
34 [NotifyCanExecuteChangedFor(nameof(InstallCommand))]
35 private bool _isPulling;
36
37 [ObservableProperty]
38 private string _progressText = "";
39
40 [ObservableProperty]
41 private string _errorText = "";
42
43 [RelayCommand(CanExecute = nameof(CanInstall))]
44 private async Task InstallAsync()
45 {
46 var model = SelectedRecommended?.ModelName ?? CustomModelName?.Trim() ?? "";
47 if (string.IsNullOrEmpty(model))
48 return;
49
50 ErrorText = "";
51 IsPulling = true;
52 ProgressText = $"Скачивание {model}…";
53
54 try
55 {
56 await foreach (var status in _ollama.PullModelAsync(model, CancellationToken.None))
57 {
58 var s = status;
59 UiScheduler.Default.Post(() => ProgressText = s);
60 }
61 await UiScheduler.Default.InvokeAsync(() =>
62 {
63 ProgressText = "Готово.";
64 _closeRequested();
65 });
66 }
67 catch (Exception ex)
68 {
69 await UiScheduler.Default.InvokeAsync(() => ErrorText = ex.Message);
70 }
71 finally
72 {
73 await UiScheduler.Default.InvokeAsync(() => IsPulling = false);
74 }
75 }
76
77 private bool CanInstall() => !IsPulling && (!string.IsNullOrWhiteSpace(CustomModelName) || SelectedRecommended is not null);
78
79 partial void OnCustomModelNameChanged(string value)
80 {
81 if (!string.IsNullOrWhiteSpace(value))
82 SelectedRecommended = null;
83 }
84
85 [RelayCommand]
86 private void Cancel()
87 {
88 _closeRequested();
89 }
90
91 [RelayCommand]
92 private void SelectRecommended(Models.RecommendedModel? model)
93 {
94 if (model is null) return;
95 SelectedRecommended = model;
96 CustomModelName = "";
97 }
98}
99
View only · write via MCP/CIDE