44 */
55package fr .totetmatt .blueskygephi ;
66
7+ import fr .totetmatt .blueskygephi .atproto .AtProtoException ;
78import java .awt .Color ;
89import java .awt .Desktop ;
910import java .io .IOException ;
1011import java .net .URI ;
1112import java .util .Arrays ;
1213import java .util .List ;
14+ import java .util .concurrent .ExecutionException ;
1315import java .util .logging .Logger ;
1416import java .util .stream .Collectors ;
17+ import javax .swing .Icon ;
18+ import javax .swing .UIManager ;
1519import org .openide .awt .ActionID ;
1620import org .openide .awt .ActionReference ;
21+ import org .openide .awt .NotificationDisplayer ;
1722import org .openide .util .Exceptions ;
1823import org .openide .util .Lookup ;
1924import org .openide .util .NbBundle ;
@@ -75,6 +80,7 @@ private void initComponents() {
7580 credentialsPasswordLabel = new javax .swing .JLabel ();
7681 credentialsPasswordField = new javax .swing .JPasswordField ();
7782 credentialsConnectButton = new javax .swing .JButton ();
83+ credentialsCheckButton = new javax .swing .JButton ();
7884 jScrollPane1 = new javax .swing .JScrollPane ();
7985 handleSearchTextArea = new javax .swing .JTextArea ();
8086 fetchLabel = new javax .swing .JLabel ();
@@ -123,6 +129,14 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
123129 }
124130 });
125131
132+ org .openide .awt .Mnemonics .setLocalizedText (credentialsCheckButton , org .openide .util .NbBundle .getMessage (BlueskyGephiMainPanel .class , "BlueskyGephiMainPanel.credentialsCheckButton.text" )); // NOI18N
133+ credentialsCheckButton .setToolTipText (org .openide .util .NbBundle .getMessage (BlueskyGephiMainPanel .class , "BlueskyGephiMainPanel.credentialsCheckButton.toolTipText" )); // NOI18N
134+ credentialsCheckButton .addActionListener (new java .awt .event .ActionListener () {
135+ public void actionPerformed (java .awt .event .ActionEvent evt ) {
136+ credentialsCheckButtonActionPerformed (evt );
137+ }
138+ });
139+
126140 javax .swing .GroupLayout credentialsPanelLayout = new javax .swing .GroupLayout (credentialsPanel );
127141 credentialsPanel .setLayout (credentialsPanelLayout );
128142 credentialsPanelLayout .setHorizontalGroup (
@@ -133,30 +147,32 @@ public void actionPerformed(java.awt.event.ActionEvent evt) {
133147 .addComponent (credentialsConnectButton , javax .swing .GroupLayout .DEFAULT_SIZE , javax .swing .GroupLayout .DEFAULT_SIZE , Short .MAX_VALUE )
134148 .addGroup (credentialsPanelLayout .createSequentialGroup ()
135149 .addGroup (credentialsPanelLayout .createParallelGroup (javax .swing .GroupLayout .Alignment .LEADING )
136- .addComponent (credentialsPasswordLabel )
137- .addComponent (credentialsHandleLabel ))
150+ .addComponent (credentialsHandleLabel )
151+ .addComponent (credentialsHostLabel )
152+ .addComponent (credentialsPasswordLabel ))
138153 .addGap (18 , 18 , 18 )
139154 .addGroup (credentialsPanelLayout .createParallelGroup (javax .swing .GroupLayout .Alignment .LEADING )
140155 .addComponent (credentialsHandleField , javax .swing .GroupLayout .DEFAULT_SIZE , 263 , Short .MAX_VALUE )
141- .addComponent (credentialsPasswordField )))
142- .addGroup (credentialsPanelLayout .createSequentialGroup ()
143- .addComponent (credentialsHostLabel )
144- . addGap ( 43 , 43 , 43 )
145- . addComponent ( credentialsHostField , javax . swing . GroupLayout . DEFAULT_SIZE , 263 , Short . MAX_VALUE )))
156+ .addComponent (credentialsPasswordField )
157+ .addGroup (credentialsPanelLayout .createSequentialGroup ()
158+ .addComponent (credentialsHostField , javax . swing . GroupLayout . DEFAULT_SIZE , 263 , Short . MAX_VALUE )
159+ . addPreferredGap ( javax . swing . LayoutStyle . ComponentPlacement . RELATED )
160+ . addComponent ( credentialsCheckButton )) )))
146161 .addContainerGap ())
147162 );
148163 credentialsPanelLayout .setVerticalGroup (
149164 credentialsPanelLayout .createParallelGroup (javax .swing .GroupLayout .Alignment .LEADING )
150165 .addGroup (javax .swing .GroupLayout .Alignment .TRAILING , credentialsPanelLayout .createSequentialGroup ()
151166 .addGap (0 , 9 , Short .MAX_VALUE )
152- .addGroup (credentialsPanelLayout .createParallelGroup (javax .swing .GroupLayout .Alignment .BASELINE )
153- .addComponent (credentialsHostLabel )
154- .addComponent (credentialsHostField , javax .swing .GroupLayout .PREFERRED_SIZE , javax .swing .GroupLayout .DEFAULT_SIZE , javax .swing .GroupLayout .PREFERRED_SIZE ))
155- .addPreferredGap (javax .swing .LayoutStyle .ComponentPlacement .UNRELATED )
156167 .addGroup (credentialsPanelLayout .createParallelGroup (javax .swing .GroupLayout .Alignment .BASELINE )
157168 .addComponent (credentialsHandleLabel )
158169 .addComponent (credentialsHandleField , javax .swing .GroupLayout .PREFERRED_SIZE , javax .swing .GroupLayout .DEFAULT_SIZE , javax .swing .GroupLayout .PREFERRED_SIZE ))
159170 .addPreferredGap (javax .swing .LayoutStyle .ComponentPlacement .UNRELATED )
171+ .addGroup (credentialsPanelLayout .createParallelGroup (javax .swing .GroupLayout .Alignment .BASELINE )
172+ .addComponent (credentialsHostLabel )
173+ .addComponent (credentialsHostField , javax .swing .GroupLayout .PREFERRED_SIZE , javax .swing .GroupLayout .DEFAULT_SIZE , javax .swing .GroupLayout .PREFERRED_SIZE )
174+ .addComponent (credentialsCheckButton ))
175+ .addPreferredGap (javax .swing .LayoutStyle .ComponentPlacement .UNRELATED )
160176 .addGroup (credentialsPanelLayout .createParallelGroup (javax .swing .GroupLayout .Alignment .BASELINE )
161177 .addComponent (credentialsPasswordLabel )
162178 .addComponent (credentialsPasswordField , javax .swing .GroupLayout .PREFERRED_SIZE , javax .swing .GroupLayout .DEFAULT_SIZE , javax .swing .GroupLayout .PREFERRED_SIZE ))
@@ -297,6 +313,50 @@ protected void done() {
297313 }.execute ();
298314 }//GEN-LAST:event_credentialsConnectButtonActionPerformed
299315
316+ private void credentialsCheckButtonActionPerformed (java .awt .event .ActionEvent evt ) {//GEN-FIRST:event_credentialsCheckButtonActionPerformed
317+ final String handle = credentialsHandleField .getText ();
318+ // Resolve the account's PDS host off the EDT so a slow lookup never freezes the UI.
319+ credentialsCheckButton .setEnabled (false );
320+ credentialsCheckButton .setBackground (Color .ORANGE );
321+ new javax .swing .SwingWorker <String , Void >() {
322+ @ Override
323+ protected String doInBackground () {
324+ return blueskyGephi .resolveHostFromHandle (handle );
325+ }
326+
327+ @ Override
328+ protected void done () {
329+ try {
330+ String host = get ();
331+ credentialsHostField .setText (host );
332+ credentialsCheckButton .setBackground (Color .GREEN );
333+ } catch (InterruptedException ex ) {
334+ Thread .currentThread ().interrupt ();
335+ credentialsCheckButton .setBackground (Color .RED );
336+ } catch (ExecutionException ex ) {
337+ credentialsCheckButton .setBackground (Color .RED );
338+ Throwable cause = (ex .getCause () != null ) ? ex .getCause () : ex ;
339+ String detail = (cause instanceof AtProtoException )
340+ ? ((AtProtoException ) cause ).getUserMessageWithContent ()
341+ : String .valueOf (cause .getMessage ());
342+ consoleLogger .warning ("Host check failed for \" " + handle + "\" : " + detail );
343+ notifyError ("Bluesky: could not determine host from handle" , detail );
344+ } finally {
345+ credentialsCheckButton .setEnabled (true );
346+ }
347+ }
348+ }.execute ();
349+ }//GEN-LAST:event_credentialsCheckButtonActionPerformed
350+
351+ private void notifyError (String title , String detail ) {
352+ Icon icon = UIManager .getIcon ("OptionPane.warningIcon" );
353+ if (icon == null ) {
354+ icon = new javax .swing .ImageIcon (
355+ new java .awt .image .BufferedImage (16 , 16 , java .awt .image .BufferedImage .TYPE_INT_ARGB ));
356+ }
357+ NotificationDisplayer .getDefault ().notify (title , icon , detail , null , NotificationDisplayer .Priority .HIGH );
358+ }
359+
300360 private void runFetchButtonActionPerformed (java .awt .event .ActionEvent evt ) {//GEN-FIRST:event_runFetchButtonActionPerformed
301361 blueskyGephi .setQuery (handleSearchTextArea .getText ());
302362 List <String > actors = Arrays .asList (handleSearchTextArea .getText ().split ("\\ n" ))
@@ -339,6 +399,7 @@ private void credentialsHostFieldActionPerformed(java.awt.event.ActionEvent evt)
339399
340400
341401 // Variables declaration - do not modify//GEN-BEGIN:variables
402+ private javax .swing .JButton credentialsCheckButton ;
342403 private javax .swing .JButton credentialsConnectButton ;
343404 private javax .swing .JTextField credentialsHandleField ;
344405 private javax .swing .JLabel credentialsHandleLabel ;
0 commit comments