DreamineVMS 1.0.0.0
Windows PC의 RTSP·USB 카메라 영상을 HLS로 변환해 원격 CCTV Viewer에 전달하는 데스크톱 에이전트입니다.
로딩중...
검색중...
일치하는것 없음
AgentSettingsViewModel.cs
이 파일의 문서화 페이지로 가기
2using Microsoft.Extensions.Configuration;
3using System.ComponentModel;
4using System.Runtime.CompilerServices;
5using System.Windows.Input;
6
8
17public sealed class AgentSettingsViewModel : INotifyPropertyChanged
18{
27 private readonly AgentApiClient _api;
36 private readonly AgentSettingsWriter _writer;
37
46 private string _serverUrl = "";
55 private string _email = "";
64 private string _password = "";
73 private string _statusMessage = "저장된 설정을 불러왔습니다.";
82 private bool _isConnected = false;
83
116 public AgentSettingsViewModel(IConfiguration config, AgentApiClient api, AgentSettingsWriter writer)
117 {
118 _api = api;
119 _writer = writer;
120
121 // 현재 설정값으로 초기화
122 _serverUrl = config["Agent:ServerUrl"] ?? "http://cctvviewer.codemaru.co.kr";
123 _email = config["Agent:Email"] ?? "";
124 _password = config["Agent:Password"] ?? "";
125
129
130 // 현재 연결 상태 반영
131 _isConnected = _api.Token is not null;
132 _statusMessage = _isConnected ? $"연결됨 — 토큰 보유 중" : "미연결 — 저장 후 '재연결'을 눌러주세요.";
133 }
134
143 public event PropertyChangedEventHandler? PropertyChanged;
144
153 public string ServerUrl
154 {
155 get => _serverUrl;
156 set => SetField(ref _serverUrl, value);
157 }
158
167 public string Email
168 {
169 get => _email;
170 set => SetField(ref _email, value);
171 }
172
181 public string Password
182 {
183 get => _password;
184 set => SetField(ref _password, value);
185 }
186
195 public string StatusMessage
196 {
197 get => _statusMessage;
198 private set => SetField(ref _statusMessage, value);
199 }
200
209 public bool IsConnected
210 {
211 get => _isConnected;
212 private set => SetField(ref _isConnected, value);
213 }
214
223 public ICommand SaveCommand { get; }
232 public ICommand TestCommand { get; }
241 public ICommand ReconnectCommand { get; }
242
259 private async Task SaveAsync()
260 {
261 if (string.IsNullOrWhiteSpace(ServerUrl))
262 {
263 StatusMessage = "서버 URL을 입력하세요.";
264 return;
265 }
266 if (string.IsNullOrWhiteSpace(Email))
267 {
268 StatusMessage = "이메일을 입력하세요.";
269 return;
270 }
271 if (string.IsNullOrWhiteSpace(Password))
272 {
273 StatusMessage = "비밀번호를 입력하세요.";
274 return;
275 }
276
277 try
278 {
279 await _writer.SaveAsync(ServerUrl.Trim(), Email.Trim(), Password, CancellationToken.None)
280 .ConfigureAwait(true);
281
282 // 실행 중인 ApiClient에도 즉시 반영
283 _api.SetCredentials(ServerUrl.Trim(), Email.Trim(), Password);
284 IsConnected = false;
285 StatusMessage = "설정을 저장했습니다. '재연결'을 눌러 서버에 연결하세요.";
286 }
287 catch (Exception ex)
288 {
289 StatusMessage = $"저장 실패: {ex.Message}";
290 }
291 }
292
309 private async Task TestConnectionAsync()
310 {
311 if (string.IsNullOrWhiteSpace(Email) || string.IsNullOrWhiteSpace(Password))
312 {
313 StatusMessage = "이메일과 비밀번호를 먼저 입력하세요.";
314 return;
315 }
316
317 StatusMessage = "서버에 연결 테스트 중...";
318 var (ok, err) = await _api.LoginAsync(Email.Trim(), Password).ConfigureAwait(true);
319 IsConnected = ok;
320 StatusMessage = ok
321 ? $"연결 성공! 서버: {_api.ServerUrl}"
322 : $"연결 실패: {err}";
323 }
324
341 private async Task ReconnectAsync()
342 {
343 StatusMessage = "재연결 시도 중...";
344 IsConnected = false;
345 _api.ClearToken();
346
347 var (ok, err) = await _api.LoginWithStoredCredentialsAsync().ConfigureAwait(true);
348 IsConnected = ok;
349 StatusMessage = ok
350 ? $"재연결 성공! 서버: {_api.ServerUrl}"
351 : $"재연결 실패: {err}";
352 }
353
402 private bool SetField<T>(ref T field, T value, [CallerMemberName] string? name = null)
403 {
404 if (EqualityComparer<T>.Default.Equals(field, value)) return false;
405 field = value;
406 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
407 return true;
408 }
409}
AgentSettingsViewModel(IConfiguration config, AgentApiClient api, AgentSettingsWriter writer)
bool SetField< T >(ref T field, T value, [CallerMemberName] string? name=null)