Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit9e50acd

Browse files
authored
chore: make hostname suffix mutable in views (#102)
Part 1 of#49Makes the workspace suffix dynamic in the views. A later PR in this stack will fetch the suffix and apply it to any views if it changes.If the suffix doesn't match the FQDN provided by the VPN service, we won't gray out anything when we show the name, but if we later get a suffix that matches, it will update.
1 parentcd845d4 commit9e50acd

File tree

4 files changed

+99
-41
lines changed

4 files changed

+99
-41
lines changed

‎App/ViewModels/AgentViewModel.cs

Lines changed: 82 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,13 @@ namespace Coder.Desktop.App.ViewModels;
2323

2424
publicinterfaceIAgentViewModelFactory
2525
{
26-
publicAgentViewModelCreate(IAgentExpanderHostexpanderHost,Uuidid,stringhostname,stringhostnameSuffix,
26+
publicAgentViewModelCreate(IAgentExpanderHostexpanderHost,Uuidid,stringfullyQualifiedDomainName,
27+
stringhostnameSuffix,
2728
AgentConnectionStatusconnectionStatus,UridashboardBaseUrl,string?workspaceName);
29+
30+
publicAgentViewModelCreateDummy(IAgentExpanderHostexpanderHost,Uuidid,
31+
stringhostnameSuffix,
32+
AgentConnectionStatusconnectionStatus,UridashboardBaseUrl,stringworkspaceName);
2833
}
2934

3035
publicclassAgentViewModelFactory(
@@ -33,14 +38,32 @@ public class AgentViewModelFactory(
3338
ICredentialManagercredentialManager,
3439
IAgentAppViewModelFactoryagentAppViewModelFactory):IAgentViewModelFactory
3540
{
36-
publicAgentViewModelCreate(IAgentExpanderHostexpanderHost,Uuidid,stringhostname,stringhostnameSuffix,
41+
publicAgentViewModelCreate(IAgentExpanderHostexpanderHost,Uuidid,stringfullyQualifiedDomainName,
42+
stringhostnameSuffix,
3743
AgentConnectionStatusconnectionStatus,UridashboardBaseUrl,string?workspaceName)
3844
{
3945
returnnewAgentViewModel(childLogger,coderApiClientFactory,credentialManager,agentAppViewModelFactory,
4046
expanderHost,id)
4147
{
42-
Hostname=hostname,
43-
HostnameSuffix=hostnameSuffix,
48+
ConfiguredFqdn=fullyQualifiedDomainName,
49+
ConfiguredHostname=string.Empty,
50+
ConfiguredHostnameSuffix=hostnameSuffix,
51+
ConnectionStatus=connectionStatus,
52+
DashboardBaseUrl=dashboardBaseUrl,
53+
WorkspaceName=workspaceName,
54+
};
55+
}
56+
57+
publicAgentViewModelCreateDummy(IAgentExpanderHostexpanderHost,Uuidid,
58+
stringhostnameSuffix,
59+
AgentConnectionStatusconnectionStatus,UridashboardBaseUrl,stringworkspaceName)
60+
{
61+
returnnewAgentViewModel(childLogger,coderApiClientFactory,credentialManager,agentAppViewModelFactory,
62+
expanderHost,id)
63+
{
64+
ConfiguredFqdn=string.Empty,
65+
ConfiguredHostname=workspaceName,
66+
ConfiguredHostnameSuffix=hostnameSuffix,
4467
ConnectionStatus=connectionStatus,
4568
DashboardBaseUrl=dashboardBaseUrl,
4669
WorkspaceName=workspaceName,
@@ -84,15 +107,55 @@ public partial class AgentViewModel : ObservableObject, IModelUpdateable<AgentVi
84107

85108
publicreadonlyUuidId;
86109

110+
// This is set only for "dummy" agents that represent unstarted workspaces. If set, then ConfiguredFqdn
111+
// should be empty, otherwise it will override this.
112+
[ObservableProperty]
113+
[NotifyPropertyChangedFor(nameof(ViewableHostname))]
114+
[NotifyPropertyChangedFor(nameof(ViewableHostnameSuffix))]
115+
[NotifyPropertyChangedFor(nameof(FullyQualifiedDomainName))]
116+
publicrequiredpartialstringConfiguredHostname{get;set;}
117+
118+
// This should be set if we have an FQDN from the VPN service, and overrides ConfiguredHostname if set.
87119
[ObservableProperty]
88-
[NotifyPropertyChangedFor(nameof(FullHostname))]
89-
publicrequiredpartialstringHostname{get;set;}
120+
[NotifyPropertyChangedFor(nameof(ViewableHostname))]
121+
[NotifyPropertyChangedFor(nameof(ViewableHostnameSuffix))]
122+
[NotifyPropertyChangedFor(nameof(FullyQualifiedDomainName))]
123+
publicrequiredpartialstringConfiguredFqdn{get;set;}
90124

91125
[ObservableProperty]
92-
[NotifyPropertyChangedFor(nameof(FullHostname))]
93-
publicrequiredpartialstringHostnameSuffix{get;set;}// including leading dot
126+
[NotifyPropertyChangedFor(nameof(ViewableHostname))]
127+
[NotifyPropertyChangedFor(nameof(ViewableHostnameSuffix))]
128+
[NotifyPropertyChangedFor(nameof(FullyQualifiedDomainName))]
129+
publicrequiredpartialstringConfiguredHostnameSuffix{get;set;}// including leading dot
130+
131+
132+
publicstringFullyQualifiedDomainName
133+
{
134+
get
135+
{
136+
if(!string.IsNullOrEmpty(ConfiguredFqdn))returnConfiguredFqdn;
137+
returnConfiguredHostname+ConfiguredHostnameSuffix;
138+
}
139+
}
94140

95-
publicstringFullHostname=>Hostname+HostnameSuffix;
141+
/// <summary>
142+
/// ViewableHostname is the hostname portion of the fully qualified domain name (FQDN) specifically for
143+
/// views that render it differently than the suffix. If the ConfiguredHostnameSuffix doesn't actually
144+
/// match the FQDN, then this will be the entire FQDN, and ViewableHostnameSuffix will be empty.
145+
/// </summary>
146+
publicstringViewableHostname=>!FullyQualifiedDomainName.EndsWith(ConfiguredHostnameSuffix)
147+
?FullyQualifiedDomainName
148+
:FullyQualifiedDomainName[0..^ConfiguredHostnameSuffix.Length];
149+
150+
/// <summary>
151+
/// ViewableHostnameSuffix is the domain suffix portion (including leading dot) of the fully qualified
152+
/// domain name (FQDN) specifically for views that render it differently from the rest of the FQDN. If
153+
/// the ConfiguredHostnameSuffix doesn't actually match the FQDN, then this will be empty and the
154+
/// ViewableHostname will contain the entire FQDN.
155+
/// </summary>
156+
publicstringViewableHostnameSuffix=>FullyQualifiedDomainName.EndsWith(ConfiguredHostnameSuffix)
157+
?ConfiguredHostnameSuffix
158+
:string.Empty;
96159

97160
[ObservableProperty]
98161
[NotifyPropertyChangedFor(nameof(ShowExpandAppsMessage))]
@@ -202,10 +265,12 @@ public bool TryApplyChanges(AgentViewModel model)
202265

203266
// To avoid spurious UI updates which cause flashing, don't actually
204267
// write to values unless they've changed.
205-
if(Hostname!=model.Hostname)
206-
Hostname=model.Hostname;
207-
if(HostnameSuffix!=model.HostnameSuffix)
208-
HostnameSuffix=model.HostnameSuffix;
268+
if(ConfiguredFqdn!=model.ConfiguredFqdn)
269+
ConfiguredFqdn=model.ConfiguredFqdn;
270+
if(ConfiguredHostname!=model.ConfiguredHostname)
271+
ConfiguredHostname=model.ConfiguredHostname;
272+
if(ConfiguredHostnameSuffix!=model.ConfiguredHostnameSuffix)
273+
ConfiguredHostnameSuffix=model.ConfiguredHostnameSuffix;
209274
if(ConnectionStatus!=model.ConnectionStatus)
210275
ConnectionStatus=model.ConnectionStatus;
211276
if(DashboardBaseUrl!=model.DashboardBaseUrl)
@@ -337,12 +402,13 @@ private void ContinueFetchApps(Task<WorkspaceAgent> task)
337402
{
338403
Scheme=scheme,
339404
Host="vscode-remote",
340-
Path=$"/ssh-remote+{FullHostname}/{workspaceAgent.ExpandedDirectory}",
405+
Path=$"/ssh-remote+{FullyQualifiedDomainName}/{workspaceAgent.ExpandedDirectory}",
341406
}.Uri;
342407
}
343408
catch(Exceptione)
344409
{
345-
_logger.LogWarning(e,"Could not craft app URI for display app {displayApp}, app will not appear in list",
410+
_logger.LogWarning(e,
411+
"Could not craft app URI for display app {displayApp}, app will not appear in list",
346412
displayApp);
347413
continue;
348414
}
@@ -365,7 +431,7 @@ private void CopyHostname(object parameter)
365431
{
366432
RequestedOperation=DataPackageOperation.Copy,
367433
};
368-
dataPackage.SetText(FullHostname);
434+
dataPackage.SetText(FullyQualifiedDomainName);
369435
Clipboard.SetContent(dataPackage);
370436

371437
if(parameteris notFrameworkElementframeworkElement)return;

‎App/ViewModels/TrayWindowViewModel.cs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public partial class TrayWindowViewModel : ObservableObject, IAgentExpanderHost
2929
{
3030
privateconstintMaxAgents=5;
3131
privateconststringDefaultDashboardUrl="https://coder.com";
32+
privateconststringDefaultHostnameSuffix=".coder";
3233

3334
privatereadonlyIServiceProvider_services;
3435
privatereadonlyIRpcController_rpcController;
@@ -90,6 +91,8 @@ public partial class TrayWindowViewModel : ObservableObject, IAgentExpanderHost
9091

9192
[ObservableProperty]publicpartialstringDashboardUrl{get;set;}=DefaultDashboardUrl;
9293

94+
privatestring_hostnameSuffix=DefaultHostnameSuffix;
95+
9396
publicTrayWindowViewModel(IServiceProviderservices,IRpcControllerrpcController,
9497
ICredentialManagercredentialManager,IAgentViewModelFactoryagentViewModelFactory)
9598
{
@@ -181,14 +184,6 @@ private void UpdateFromRpcModel(RpcModel rpcModel)
181184
if(string.IsNullOrWhiteSpace(fqdn))
182185
continue;
183186

184-
varfqdnPrefix=fqdn;
185-
varfqdnSuffix="";
186-
if(fqdn.Contains('.'))
187-
{
188-
fqdnPrefix=fqdn[..fqdn.LastIndexOf('.')];
189-
fqdnSuffix=fqdn[fqdn.LastIndexOf('.')..];
190-
}
191-
192187
varlastHandshakeAgo=DateTime.UtcNow.Subtract(agent.LastHandshake.ToDateTime());
193188
varconnectionStatus=lastHandshakeAgo<TimeSpan.FromMinutes(5)
194189
?AgentConnectionStatus.Green
@@ -199,8 +194,8 @@ private void UpdateFromRpcModel(RpcModel rpcModel)
199194
agents.Add(_agentViewModelFactory.Create(
200195
this,
201196
uuid,
202-
fqdnPrefix,
203-
fqdnSuffix,
197+
fqdn,
198+
_hostnameSuffix,
204199
connectionStatus,
205200
credentialModel.CoderUrl,
206201
workspace?.Name));
@@ -214,15 +209,12 @@ private void UpdateFromRpcModel(RpcModel rpcModel)
214209
if(!Uuid.TryFrom(workspace.Id.Span,outvaruuid))
215210
continue;
216211

217-
agents.Add(_agentViewModelFactory.Create(
212+
agents.Add(_agentViewModelFactory.CreateDummy(
218213
this,
219214
// Workspace ID is fine as a stand-in here, it shouldn't
220215
// conflict with any agent IDs.
221216
uuid,
222-
// We assume that it's a single-agent workspace.
223-
workspace.Name,
224-
// TODO: this needs to get the suffix from the server
225-
".coder",
217+
_hostnameSuffix,
226218
AgentConnectionStatus.Gray,
227219
credentialModel.CoderUrl,
228220
workspace.Name));
@@ -233,7 +225,7 @@ private void UpdateFromRpcModel(RpcModel rpcModel)
233225
{
234226
if(a.ConnectionStatus!=b.ConnectionStatus)
235227
returna.ConnectionStatus.CompareTo(b.ConnectionStatus);
236-
returnstring.Compare(a.FullHostname,b.FullHostname,StringComparison.Ordinal);
228+
returnstring.Compare(a.FullyQualifiedDomainName,b.FullyQualifiedDomainName,StringComparison.Ordinal);
237229
});
238230

239231
if(Agents.Count<MaxAgents)ShowAllAgents=false;

‎App/Views/Pages/TrayWindowMainPage.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,9 @@
169169
TextTrimming="CharacterEllipsis"
170170
TextWrapping="NoWrap">
171171

172-
<RunText="{x:BindHostname, Mode=OneWay}"
172+
<RunText="{x:BindViewableHostname, Mode=OneWay}"
173173
Foreground="{ThemeResource DefaultTextForegroundThemeBrush}" />
174-
<RunText="{x:BindHostnameSuffix, Mode=OneWay}"
174+
<RunText="{x:BindViewableHostnameSuffix, Mode=OneWay}"
175175
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}" />
176176
</TextBlock>
177177

‎App/Views/Pages/TrayWindowMainPage.xaml.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,22 @@ public TrayWindowMainPage(TrayWindowViewModel viewModel)
1818
}
1919

2020
// HACK: using XAML to populate the text Runs results in an additional
21-
// whitespace Run being inserted between theHostname and the
22-
//HostnameSuffix. You might think, "OK let's populate the entire TextBlock
23-
// content from code then!", but this results in the ItemsRepeater
21+
// whitespace Run being inserted between theViewableHostname and the
22+
//ViewableHostnameSuffix. You might think, "OK let's populate the entire
23+
//TextBlockcontent from code then!", but this results in the ItemsRepeater
2424
// corrupting it and firing events off to the wrong AgentModel.
2525
//
2626
// This is the best solution I came up with that worked.
2727
publicvoidAgentHostnameText_OnLoaded(objectsender,RoutedEventArgse)
2828
{
2929
if(senderis notTextBlocktextBlock)return;
3030

31-
varnonEmptyRuns=newList<Run>();
31+
varnonWhitespaceRuns=newList<Run>();
3232
foreach(varinlineintextBlock.Inlines)
33-
if(inlineisRunrun&&!string.IsNullOrWhiteSpace(run.Text))
34-
nonEmptyRuns.Add(run);
33+
if(inlineisRunrun&&run.Text!=" ")
34+
nonWhitespaceRuns.Add(run);
3535

3636
textBlock.Inlines.Clear();
37-
foreach(varruninnonEmptyRuns)textBlock.Inlines.Add(run);
37+
foreach(varruninnonWhitespaceRuns)textBlock.Inlines.Add(run);
3838
}
3939
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp