Skip to content

Commit 0c20755

Browse files
committed
fix: Change most of the pop-up windows to non-modal dialogs to prevent the main window from freezing when a pop-up appears on the remote desktop. #791
1 parent 3c0761b commit 0c20755

26 files changed

+649
-459
lines changed

Ui/Model/TagActionHelper.cs

Lines changed: 65 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using _1RM.View;
88
using _1RM.View.ServerList;
99
using _1RM.View.Utils;
10+
using Shawn.Utils;
1011
using Shawn.Utils.Interface;
1112

1213
namespace _1RM.Model;
@@ -68,73 +69,84 @@ public static void CmdTagDelete(object? o)
6869
IoC.Get<ServerListPageViewModel>().CmdShowMainTab?.Execute();
6970
}
7071

71-
public static void CmdTagRename(object? o)
72+
public static async void CmdTagRename(object? o)
7273
{
73-
var tagName = GetTagNameFromObject(o);
74-
if (string.IsNullOrEmpty(tagName))
75-
return;
76-
77-
string oldTagName = tagName!;
78-
var protocolServerBases = IoC.Get<GlobalData>().VmItemList.Where(x => x.Server.Tags.Contains(oldTagName) && x.IsEditable).Select(x => x.Server).ToArray();
79-
if (protocolServerBases.Any() != true)
74+
try
8075
{
81-
return;
82-
}
76+
var tagName = GetTagNameFromObject(o);
77+
if (string.IsNullOrEmpty(tagName))
78+
return;
8379

84-
var newTagName = InputBoxViewModel.GetValue(IoC.Translate("Tags"), new Func<string, string>((str) =>
85-
{
86-
if (string.IsNullOrWhiteSpace(str))
87-
return IoC.Translate(LanguageService.CAN_NOT_BE_EMPTY);
88-
if (str == tagName)
80+
string oldTagName = tagName!;
81+
var protocolServerBases = IoC.Get<GlobalData>().VmItemList.Where(x => x.Server.Tags.Contains(oldTagName) && x.IsEditable).Select(x => x.Server).ToArray();
82+
if (protocolServerBases.Any() != true)
83+
{
84+
return;
85+
}
86+
87+
var newTagName = await InputBoxViewModel.GetValue(IoC.Translate("Tags"), new Func<string, string>((str) =>
88+
{
89+
if (string.IsNullOrWhiteSpace(str))
90+
return IoC.Translate(LanguageService.CAN_NOT_BE_EMPTY);
91+
if (str == tagName)
92+
return "";
93+
if (IoC.Get<GlobalData>().TagList.Any(x => x.Name == str))
94+
return IoC.Translate(LanguageService.XXX_IS_ALREADY_EXISTED, str);
8995
return "";
90-
if (IoC.Get<GlobalData>().TagList.Any(x => x.Name == str))
91-
return IoC.Translate(LanguageService.XXX_IS_ALREADY_EXISTED, str);
92-
return "";
93-
}), defaultResponse: tagName!, ownerViewModel: IoC.Get<MainWindowViewModel>());
96+
}), defaultResponse: tagName!, ownerViewModel: IoC.Get<MainWindowViewModel>());
9497

95-
newTagName = TagAndKeywordEncodeHelper.RectifyTagName(newTagName);
96-
if (string.IsNullOrEmpty(newTagName) || oldTagName == newTagName)
97-
return;
98+
newTagName = TagAndKeywordEncodeHelper.RectifyTagName(newTagName);
99+
if (string.IsNullOrEmpty(newTagName) || oldTagName == newTagName)
100+
return;
98101

99-
// 1. update is pin
100-
var oldTag = LocalityTagService.GetAndRemoveTag(oldTagName);
101-
if (oldTag != null)
102-
{
103-
oldTag.Name = newTagName;
104-
LocalityTagService.UpdateTag(oldTag);
105-
}
102+
// 1. update is pin
103+
var oldTag = LocalityTagService.GetAndRemoveTag(oldTagName);
104+
if (oldTag != null)
105+
{
106+
oldTag.Name = newTagName;
107+
LocalityTagService.UpdateTag(oldTag);
108+
}
106109

107-
// 2. update server tags
108-
foreach (var server in protocolServerBases)
109-
{
110-
if (server.Tags.Contains(oldTagName))
110+
// 2. update server tags
111+
foreach (var server in protocolServerBases)
111112
{
112-
var tags = new List<string>(server.Tags);
113-
tags.Remove(oldTagName);
114-
tags.Add(newTagName);
115-
server.Tags = tags;
113+
if (server.Tags.Contains(oldTagName))
114+
{
115+
var tags = new List<string>(server.Tags);
116+
tags.Remove(oldTagName);
117+
tags.Add(newTagName);
118+
server.Tags = tags;
119+
}
120+
}
121+
122+
// 2.5 update tags
123+
{
124+
var tag = IoC.Get<GlobalData>().TagList.FirstOrDefault(x => x.Name == oldTagName);
125+
if (tag != null) tag.Name = newTagName;
116126
}
117-
}
118127

119-
// 2.5 update tags
120-
{
121-
var tag = IoC.Get<GlobalData>().TagList.FirstOrDefault(x => x.Name == oldTagName);
122-
if (tag != null) tag.Name = newTagName;
123-
}
124128

129+
// 3. restore selected scene
130+
var tagFilters = new List<TagFilter>(IoC.Get<ServerListPageViewModel>().TagFilters);
131+
var rename = tagFilters.FirstOrDefault(x => x.TagName == oldTagName);
132+
if (rename != null)
133+
{
134+
rename.TagName = newTagName;
135+
}
136+
IoC.Get<ServerListPageViewModel>().TagFilters = tagFilters;
137+
IoC.Get<MainWindowViewModel>().SetMainFilterString(tagFilters, TagAndKeywordEncodeHelper.DecodeKeyword(IoC.Get<MainWindowViewModel>().MainFilterString).KeyWords);
125138

126-
// 3. restore selected scene
127-
var tagFilters = new List<TagFilter>(IoC.Get<ServerListPageViewModel>().TagFilters);
128-
var rename = tagFilters.FirstOrDefault(x => x.TagName == oldTagName);
129-
if (rename != null)
139+
// 4. update to db and reload tags. not tag reload
140+
IoC.Get<GlobalData>().UpdateServer(protocolServerBases, false);
141+
}
142+
catch (Exception e)
130143
{
131-
rename.TagName = newTagName;
144+
SimpleLogHelper.Error(e);
145+
SentryIoHelper.Error(e, new Dictionary<string, string>()
146+
{
147+
{"Action", "TagActionHelper.CmdTagRename"}
148+
});
132149
}
133-
IoC.Get<ServerListPageViewModel>().TagFilters = tagFilters;
134-
IoC.Get<MainWindowViewModel>().SetMainFilterString(tagFilters, TagAndKeywordEncodeHelper.DecodeKeyword(IoC.Get<MainWindowViewModel>().MainFilterString).KeyWords);
135-
136-
// 4. update to db and reload tags. not tag reload
137-
IoC.Get<GlobalData>().UpdateServer(protocolServerBases, false);
138150
}
139151

140152
public static void CmdTagConnect(object? o)

Ui/Service/SessionControlService_OpenConnection.cs

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
using _1RM.Model.ProtocolRunner.Default;
1212
using _1RM.Service.Locality;
1313
using _1RM.Utils;
14+
using _1RM.View;
1415
using _1RM.View.Editor;
1516
using _1RM.View.Host;
17+
using _1RM.View.Utils;
1618
using Shawn.Utils;
1719
using Shawn.Utils.Wpf;
1820
using Stylet;
@@ -226,49 +228,52 @@ private async Task<string> Connect(ProtocolBase protocol, string fromView, strin
226228
if (protocolClone is ProtocolBaseWithAddressPortUserPwd { AskPasswordWhenConnect: true } pb)
227229
{
228230
bool flag = false;
231+
var pwdDlg = new PasswordPopupDialogViewModel(protocolClone is SSH or SFTP)
232+
{
233+
Title = $"[{pb.ProtocolDisplayName}]({pb.DisplayName}) -> {pb.Address}:{pb.Port}",
234+
UserName = pb.UserName
235+
};
236+
if (pb.UsePrivateKeyForConnect == true)
237+
{
238+
pwdDlg.CanUsePrivateKeyForConnect = true;
239+
pwdDlg.UsePrivateKeyForConnect = true;
240+
pwdDlg.PrivateKey = pb.PrivateKey;
241+
}
242+
else
243+
{
244+
pwdDlg.UsePrivateKeyForConnect = false;
245+
pwdDlg.Password = pb.Password;
246+
}
247+
229248
Execute.OnUIThreadSync(() =>
230249
{
231-
var pwdDlg = new PasswordPopupDialogViewModel(protocolClone is SSH or SFTP)
232-
{
233-
Title = $"[{pb.ProtocolDisplayName}]({pb.DisplayName}) -> {pb.Address}:{pb.Port}",
234-
UserName = pb.UserName
235-
};
236-
if (pb.UsePrivateKeyForConnect == true)
237-
{
238-
pwdDlg.CanUsePrivateKeyForConnect = true;
239-
pwdDlg.UsePrivateKeyForConnect = true;
240-
pwdDlg.PrivateKey = pb.PrivateKey;
241-
}
242-
else
243-
{
244-
pwdDlg.UsePrivateKeyForConnect = false;
245-
pwdDlg.Password = pb.Password;
246-
}
250+
MaskLayerController.ShowWindowWithMask(pwdDlg);
251+
});
247252

248-
if (IoC.Get<IWindowManager>().ShowDialog(pwdDlg) == true)
253+
if (await pwdDlg.WaitDialogResult() == true)
254+
{
255+
flag = true;
256+
pb.UserName = pwdDlg.UserName;
257+
if (pwdDlg.UsePrivateKeyForConnect)
249258
{
250-
flag = true;
251-
pb.UserName = pwdDlg.UserName;
252-
if (pwdDlg.UsePrivateKeyForConnect)
253-
{
254-
pb.UsePrivateKeyForConnect = true;
255-
pb.Password = "";
256-
pb.PrivateKey = pwdDlg.PrivateKey;
257-
}
258-
else
259-
{
260-
pb.UsePrivateKeyForConnect = false;
261-
pb.PrivateKey = "";
262-
pb.Password = pwdDlg.Password;
263-
}
264-
pwdDlg.PrivateKey = "";
265-
pwdDlg.Password = "";
259+
pb.UsePrivateKeyForConnect = true;
260+
pb.Password = "";
261+
pb.PrivateKey = pwdDlg.PrivateKey;
266262
}
267263
else
268264
{
269-
pwdDlg.Password = "";
265+
pb.UsePrivateKeyForConnect = false;
266+
pb.PrivateKey = "";
267+
pb.Password = pwdDlg.Password;
270268
}
271-
});
269+
pwdDlg.PrivateKey = "";
270+
pwdDlg.Password = "";
271+
}
272+
else
273+
{
274+
pwdDlg.Password = "";
275+
}
276+
272277

273278
if (flag == false)
274279
{

Ui/View/AboutPageViewModel.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@
44
using System.Text.RegularExpressions;
55
using System.Timers;
66
using _1RM.Service;
7-
using _1RM.Utils;
87
using _1RM.View.Utils;
8+
using _1RM.View.Utils.MaskAndPop;
99
using Shawn.Utils;
1010
using Shawn.Utils.Wpf;
1111
using Shawn.Utils.Wpf.Controls;
1212
using Stylet;
1313

1414
namespace _1RM.View
1515
{
16-
public class AboutPageViewModel : NotifyPropertyChangedBaseScreen
16+
public class AboutPageViewModel : PopupBase
1717
{
1818
private readonly Timer _checkUpdateTimer;
1919

@@ -124,7 +124,7 @@ public RelayCommand CmdClose
124124
{
125125
return _cmdClose ??= new RelayCommand((o) =>
126126
{
127-
this.RequestClose(false);
127+
this.RequestClose();
128128
});
129129
}
130130
}

Ui/View/Editor/DataSourceSelectorViewModel.cs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,21 @@
22
using System.Collections.Generic;
33
using System.Diagnostics;
44
using System.Linq;
5+
using System.Threading.Tasks;
56
using _1RM.Model;
67
using _1RM.Service.DataSource.DAO;
78
using _1RM.Service;
89
using _1RM.Service.DataSource;
910
using _1RM.Service.DataSource.Model;
1011
using _1RM.Utils;
1112
using _1RM.View.Utils;
13+
using _1RM.View.Utils.MaskAndPop;
1214
using Shawn.Utils.Wpf;
1315
using Stylet;
1416

1517
namespace _1RM.View.Editor
1618
{
17-
public class DataSourceSelectorViewModel : NotifyPropertyChangedBaseScreen
19+
public class DataSourceSelectorViewModel : PopupBase
1820
{
1921
private readonly DataSourceService _dataSourceService;
2022
protected DataSourceSelectorViewModel()
@@ -106,9 +108,24 @@ public RelayCommand CmdRefreshDataSource
106108
if (IoC.Get<ConfigurationService>().AdditionalDataSource.Any())
107109
{
108110
var vm = new DataSourceSelectorViewModel();
109-
if (MaskLayerController.ShowDialogWithMask(vm) != true)
110-
return null;
111-
return IoC.Get<DataSourceService>().GetDataSource(vm.SelectedSource.DataSourceName);
111+
return MaskLayerController.ShowDialogWithMask(vm) != true ? null : IoC.Get<DataSourceService>().GetDataSource(vm.SelectedSource.DataSourceName);
112+
}
113+
else
114+
{
115+
return IoC.Get<DataSourceService>().LocalDataSource;
116+
}
117+
}
118+
119+
public static async Task<DataSourceBase?> SelectDataSourceAsync()
120+
{
121+
if (IoC.Get<ConfigurationService>().AdditionalDataSource.Any())
122+
{
123+
var vm = new DataSourceSelectorViewModel();
124+
await Execute.OnUIThreadAsync(() =>
125+
{
126+
MaskLayerController.ShowWindowWithMask(vm);
127+
});
128+
return await vm.WaitDialogResult() != true ? null : IoC.Get<DataSourceService>().GetDataSource(vm.SelectedSource.DataSourceName);
112129
}
113130
else
114131
{

Ui/View/Editor/Forms/AlternativeCredential/AlternativeCredentialEditViewModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010
using _1RM.Model.Protocol.Base;
1111
using _1RM.Service;
1212
using _1RM.Utils;
13+
using _1RM.View.Utils.MaskAndPop;
1314
using Newtonsoft.Json;
1415
using Shawn.Utils.Interface;
1516
using Shawn.Utils.Wpf;
1617
using Shawn.Utils.Wpf.FileSystem;
1718

1819
namespace _1RM.View.Editor.Forms.AlternativeCredential
1920
{
20-
public class AlternativeCredentialEditViewModel : NotifyPropertyChangedBaseScreen, IDataErrorInfo
21+
public class AlternativeCredentialEditViewModel : PopupBase, IDataErrorInfo
2122
{
2223
private readonly Model.Protocol.Base.Credential? _org = null;
2324
public Model.Protocol.Base.Credential New { get; } = new Model.Protocol.Base.Credential();

Ui/View/Editor/Forms/Argument/ArgumentEditViewModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@
88
using _1RM.Model.Protocol.Base;
99
using _1RM.Service;
1010
using _1RM.Utils;
11+
using _1RM.View.Utils.MaskAndPop;
1112
using Newtonsoft.Json;
1213
using Shawn.Utils.Wpf;
1314
using Enum = System.Enum;
1415

1516
namespace _1RM.View.Editor.Forms.Argument
1617
{
17-
public class ArgumentEditViewModel : NotifyPropertyChangedBaseScreen, IDataErrorInfo
18+
public class ArgumentEditViewModel : PopupBase, IDataErrorInfo
1819
{
1920
private readonly LocalApp _localApp;
2021
private readonly AppArgument? _org = null;

Ui/View/Editor/IconPopupDialogViewModel.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
using Shawn.Utils.Wpf;
66
using System.Windows.Media.Imaging;
77
using _1RM.Resources.Icons;
8+
using _1RM.View.Utils.MaskAndPop;
89
using Shawn.Utils.Wpf.FileSystem;
910
using Shawn.Utils.Wpf.Image;
1011

1112
namespace _1RM.View.Editor
1213
{
13-
public class IconPopupDialogViewModel : NotifyPropertyChangedBaseScreen
14+
public class IconPopupDialogViewModel : PopupBase
1415
{
1516
public IconPopupDialogViewModel(BitmapSource? icon = null)
1617
{

0 commit comments

Comments
 (0)