@@ -20,9 +20,11 @@ import com.coder.gateway.util.DialogUi
20
20
import com.coder.gateway.util.InvalidVersionException
21
21
import com.coder.gateway.util.OS
22
22
import com.coder.gateway.util.SemVer
23
+ import com.coder.gateway.util.WebUrlValidationResult
23
24
import com.coder.gateway.util.humanizeConnectionError
24
25
import com.coder.gateway.util.isCancellation
25
26
import com.coder.gateway.util.toURL
27
+ import com.coder.gateway.util.validateStrictWebUrl
26
28
import com.coder.gateway.util.withoutNull
27
29
import com.intellij.icons.AllIcons
28
30
import com.intellij.ide.ActivityTracker
@@ -78,6 +80,8 @@ import javax.swing.JLabel
78
80
import javax.swing.JTable
79
81
import javax.swing.JTextField
80
82
import javax.swing.ListSelectionModel
83
+ import javax.swing.event.DocumentEvent
84
+ import javax.swing.event.DocumentListener
81
85
import javax.swing.table.DefaultTableCellRenderer
82
86
import javax.swing.table.TableCellRenderer
83
87
@@ -133,7 +137,6 @@ class CoderWorkspacesStepView :
133
137
private var tfUrl: JTextField ? = null
134
138
private var tfUrlComment: JLabel ? = null
135
139
private var cbExistingToken: JCheckBox ? = null
136
- private var cbFallbackOnSignature: JCheckBox ? = null
137
140
138
141
private val notificationBanner = NotificationBanner ()
139
142
private var tableOfWorkspaces =
@@ -219,6 +222,31 @@ class CoderWorkspacesStepView :
219
222
// Reconnect when the enter key is pressed.
220
223
maybeAskTokenThenConnect()
221
224
}
225
+ // Add document listener to clear error when user types
226
+ document.addDocumentListener(object : DocumentListener {
227
+ override fun insertUpdate (e : DocumentEvent ? ) = clearErrorState()
228
+ override fun removeUpdate (e : DocumentEvent ? ) = clearErrorState()
229
+ override fun changedUpdate (e : DocumentEvent ? ) = clearErrorState()
230
+
231
+ private fun clearErrorState () {
232
+ tfUrlComment?.apply {
233
+ foreground = UIUtil .getContextHelpForeground()
234
+ if (tfUrl?.text.equals(client?.url?.toString())) {
235
+ text =
236
+ CoderGatewayBundle .message(
237
+ " gateway.connector.view.coder.workspaces.connect.text.connected" ,
238
+ client!! .url.host,
239
+ )
240
+ } else {
241
+ text = CoderGatewayBundle .message(
242
+ " gateway.connector.view.coder.workspaces.connect.text.comment" ,
243
+ CoderGatewayBundle .message(" gateway.connector.view.coder.workspaces.connect.text" ),
244
+ )
245
+ }
246
+ icon = null
247
+ }
248
+ }
249
+ })
222
250
}.component
223
251
button(CoderGatewayBundle .message(" gateway.connector.view.coder.workspaces.connect.text" )) {
224
252
// Reconnect when the connect button is pressed.
@@ -268,15 +296,15 @@ class CoderWorkspacesStepView :
268
296
}
269
297
row {
270
298
cell() // For alignment.
271
- checkBox(CoderGatewayBundle .message(" gateway.connector.settings.fallback-on-coder-for-signatures.title" ))
272
- .bindSelected(state::fallbackOnCoderForSignatures).applyToComponent {
273
- addActionListener { event ->
274
- state.fallbackOnCoderForSignatures = (event.source as JBCheckBox ).isSelected
275
- }
299
+ checkBox(CoderGatewayBundle .message(" gateway.connector.settings.fallback-on-coder-for-signatures.title" ))
300
+ .bindSelected(state::fallbackOnCoderForSignatures).applyToComponent {
301
+ addActionListener { event ->
302
+ state.fallbackOnCoderForSignatures = (event.source as JBCheckBox ).isSelected
276
303
}
277
- .comment(
278
- CoderGatewayBundle .message(" gateway.connector.settings.fallback-on-coder-for-signatures.comment" ),
279
- )
304
+ }
305
+ .comment(
306
+ CoderGatewayBundle .message(" gateway.connector.settings.fallback-on-coder-for-signatures.comment" ),
307
+ )
280
308
281
309
}.layout(RowLayout .PARENT_GRID )
282
310
row {
@@ -539,6 +567,15 @@ class CoderWorkspacesStepView :
539
567
component.apply () // Force bindings to be filled.
540
568
val newURL = fields.coderURL.toURL()
541
569
if (settings.requireTokenAuth) {
570
+ val result = newURL.toURI().validateStrictWebUrl()
571
+ if (result is WebUrlValidationResult .Invalid ) {
572
+ tfUrlComment.apply {
573
+ this ?.foreground = UIUtil .getErrorForeground()
574
+ this ?.text = result.reason
575
+ this ?.icon = UIUtil .getBalloonErrorIcon()
576
+ }
577
+ return
578
+ }
542
579
val pastedToken =
543
580
dialogUi.askToken(
544
581
newURL,
0 commit comments