@@ -10,28 +10,14 @@ const a = {};
1010 * @param {boolean } isUpdate - If true, indicates a manual refresh, adding "..." to the title
1111 */
1212plugin . resetStatus = function ( isUpdate ) {
13- // Reset icons to the "unknown" state (pstatus0) and ensure they are visible for the loading state
14- a . iconIPv4 . removeClass ( ) . addClass ( "icon pstatus0" ) . show ( ) ;
15- a . iconIPv6 . removeClass ( ) . addClass ( "icon pstatus0" ) . show ( ) ;
16-
17- // Hide IP address text and the separator
18- a . textIPv4 . text ( "" ) . hide ( ) ;
19- a . separator . text ( "" ) . hide ( ) ;
20- a . textIPv6 . text ( "" ) . hide ( ) ;
21-
2213 // Set a tooltip to indicate that a check is in progress
2314 let title = theUILang . checkingPort || "Checking port status..." ;
2415 if ( isUpdate ) {
2516 title += "..." ; // Append ellipsis for manual updates
2617 }
27- a . pane . prop ( "title" , title ) ;
28- } ;
29-
30- // Initial check when the plugin is first loaded
31- plugin . init = function ( ) {
32- plugin . resetStatus ( false ) ;
33- // Request the initial port status from the backend
34- theWebUI . request ( "?action=initportcheck" , [ plugin . getPortStatus , plugin ] ) ;
18+ if ( a . pane ) {
19+ a . pane . prop ( "title" , title ) ;
20+ }
3521} ;
3622
3723// Function to manually trigger an update of the port status
@@ -41,76 +27,57 @@ plugin.update = function() {
4127 theWebUI . request ( "?action=updateportcheck" , [ plugin . getPortStatus , plugin ] ) ;
4228} ;
4329
44- /**
45- * Updates the UI for a specific IP protocol (IPv4 or IPv6) based on data from the backend
46- * @param {object } data - The response data containing status for both protocols
47- * @param {string } proto - The protocol to update, either "ipv4" or "ipv6"
48- * @param {function } getStatusText - A function to retrieve the localized status string
49- * @returns {string } The formatted title line for this protocol's status
50- */
51- function updateProtocolStatus ( data , proto , getStatusText ) {
52- const isEnabled = data [ 'use_' + proto ] ;
53- const icon = ( proto === 'ipv4' ) ? a . iconIPv4 : a . iconIPv6 ;
54- const textEl = ( proto === 'ipv4' ) ? a . textIPv4 : a . textIPv6 ;
55-
56- // Handle the case where the protocol is not enabled in conf.php
57- if ( ! isEnabled ) {
58- icon . hide ( ) ;
59- textEl . hide ( ) ;
60- return "" ; // Return an empty title line if not enabled
61- }
62-
63- const status = parseInt ( data [ proto + '_status' ] ) ;
64- const address = data [ proto ] ;
65- const port = data [ proto + '_port' ] ;
66- const isAvailable = address && address !== "-" ; // Check if an IP address was returned
67-
68- // Update the icon class to reflect the current status
69- icon . removeClass ( "pstatus0 pstatus1 pstatus2" ) . addClass ( "pstatus" + status ) ;
70-
71- let titleText = "" ;
72-
73- if ( isAvailable ) {
74- icon . show ( ) ;
75- // Format display text as IP:PORT, with brackets for IPv6
76- const displayText = ( proto === 'ipv6' ) ? `[${ address } ]:${ port } ` : `${ address } :${ port } ` ;
77- textEl . text ( displayText ) . show ( ) ;
78- // Create a detailed title for the tooltip
79- titleText = `${ proto . toUpperCase ( ) } : ${ displayText } (${ getStatusText ( status ) } )` ;
80- } else {
81- // If IP is not available on the server, hide the icon and the text element
82- icon . hide ( ) ;
83- textEl . hide ( ) ;
84- // Still provide a title for debugging or information
85- titleText = `${ proto . toUpperCase ( ) } : ${ ( theUILang . notAvailable || "N/A" ) } ` ;
86- }
87- return titleText ;
88- }
89-
9030/**
9131 * Main callback to process the port status response from the backend and update the UI
9232 * @param {object } d - The JSON object received from the backend response
9333 */
9434plugin . getPortStatus = function ( d ) {
95- // Helper function to get the localized text for a status code
35+ // Always clear the pane first to rebuild the UI dynamically
36+ a . pane . empty ( ) ;
37+
9638 const getStatusText = ( statusCode ) => theUILang . portStatus [ statusCode ] || theUILang . portStatus [ 0 ] || "Unknown" ;
39+ const isIPv4Available = d . ipv4 && d . ipv4 !== "-" ;
40+ const isIPv6Available = d . ipv6 && d . ipv6 !== "-" ;
41+ const titleLines = [ ] ;
42+
43+ // Conditionally create and append the IPv4 group only if the IP is available
44+ if ( isIPv4Available ) {
45+ const status = parseInt ( d . ipv4_status ) ;
46+ const displayText = `${ d . ipv4 } :${ d . ipv4_port } ` ;
47+ const ipv4Group = $ ( "<div>" ) . attr ( "id" , "port-group-ipv4" ) . addClass ( "port-group" ) ;
48+ ipv4Group . append ( $ ( "<div>" ) . attr ( "id" , "port-icon-ipv4" ) . addClass ( "icon pstatus" + status ) ) ;
49+ ipv4Group . append ( $ ( "<span>" ) . attr ( "id" , "port-ip-text-ipv4" ) . addClass ( "d-none d-lg-block port-ip-text-segment" ) . text ( displayText ) ) ;
50+ a . pane . append ( ipv4Group ) ;
51+ titleLines . push ( `IPV4: ${ displayText } (${ getStatusText ( status ) } )` ) ;
52+ } else if ( d . use_ipv4 ) {
53+ titleLines . push ( `IPV4: ${ ( theUILang . notAvailable || "N/A" ) } ` ) ;
54+ }
55+
56+ // Conditionally create and append the separator
57+ if ( isIPv4Available && isIPv6Available ) {
58+ a . pane . append ( $ ( "<span>" ) . attr ( "id" , "port-ip-separator" ) . addClass ( "d-none d-lg-block" ) . text ( "|" ) ) ;
59+ }
9760
98- // Update the status for both IPv4 and IPv6 and collect their title lines
99- const titleLines = [
100- updateProtocolStatus ( d , 'ipv4' , getStatusText ) ,
101- updateProtocolStatus ( d , 'ipv6' , getStatusText )
102- ] . filter ( line => line ) ; // Filter out empty strings for disabled/unavailable protocols
103-
104- // Show a separator only if both protocol icons are visible
105- // The CSS 'gap' property will handle the spacing automatically
106- if ( a . iconIPv4 . is ( ":visible" ) && a . iconIPv6 . is ( ":visible" ) ) {
107- a . separator . text ( "|" ) . show ( ) ;
108- } else {
109- a . separator . text ( "" ) . hide ( ) ;
61+ // Conditionally create and append the IPv6 group only if the IP is available
62+ if ( isIPv6Available ) {
63+ const status = parseInt ( d . ipv6_status ) ;
64+ const displayText = `[${ d . ipv6 } ]:${ d . ipv6_port } ` ;
65+ const ipv6Group = $ ( "<div>" ) . attr ( "id" , "port-group-ipv6" ) . addClass ( "port-group" ) ;
66+ ipv6Group . append ( $ ( "<div>" ) . attr ( "id" , "port-icon-ipv6" ) . addClass ( "icon pstatus" + status ) ) ;
67+ ipv6Group . append ( $ ( "<span>" ) . attr ( "id" , "port-ip-text-ipv6" ) . addClass ( "d-none d-lg-block port-ip-text-segment" ) . text ( displayText ) ) ;
68+ a . pane . append ( ipv6Group ) ;
69+ titleLines . push ( `IPV6: ${ displayText } (${ getStatusText ( status ) } )` ) ;
70+ } else if ( d . use_ipv6 ) {
71+ titleLines . push ( `IPV6: ${ ( theUILang . notAvailable || "N/A" ) } ` ) ;
11072 }
11173
112- // Set the combined tooltip for the entire status pane
74+ // Set the final combined tooltip for the entire status pane
11375 a . pane . prop ( "title" , titleLines . join ( " | " ) ) ;
76+
77+ // Re-attach the context menu handler since we cleared the pane
78+ if ( plugin . canChangeMenu ( ) ) {
79+ a . pane . off ( "mousedown" , plugin . createPortMenu ) . on ( "mousedown" , plugin . createPortMenu ) ;
80+ }
11481} ;
11582
11683// Defines the AJAX request for the initial port check
@@ -139,36 +106,16 @@ plugin.createPortMenu = function(e) {
139106} ;
140107
141108plugin . onLangLoaded = function ( ) {
142- // Create status bar elements in a more readable way
143- const container = $ ( "<div>" ) . addClass ( "port-status-container" ) ;
144-
145- const ipv4Icon = $ ( "<div>" ) . attr ( "id" , "port-icon-ipv4" ) . addClass ( "icon" ) ;
146- const ipv4Text = $ ( "<span>" ) . attr ( "id" , "port-ip-text-ipv4" ) . addClass ( "d-none d-lg-block port-ip-text-segment" ) ;
147- const separator = $ ( "<span>" ) . attr ( "id" , "port-ip-separator" ) . addClass ( "d-none d-lg-block" ) ;
148- const ipv6Icon = $ ( "<div>" ) . attr ( "id" , "port-icon-ipv6" ) . addClass ( "icon" ) ;
149- const ipv6Text = $ ( "<span>" ) . attr ( "id" , "port-ip-text-ipv6" ) . addClass ( "d-none d-lg-block port-ip-text-segment" ) ;
109+ // Create a temporary loading state immediately
110+ const container = $ ( "<div>" ) . addClass ( "port-status-container" )
111+ . append ( $ ( "<div>" ) . addClass ( "icon pstatus0" ) ) ; // Add a single "unknown" icon as a placeholder
150112
151- // Assemble the elements into the container
152- container . append ( ipv4Icon , ipv4Text , separator , ipv6Icon , ipv6Text ) ;
153-
154- // Add the newly created pane to the ruTorrent status bar
155113 plugin . addPaneToStatusbar ( "port-pane" , container , - 1 , true ) ;
156-
157- // Now that the pane is in the DOM, cache all the jQuery elements for future use
158114 a . pane = $ ( "#port-pane" ) ;
159- a . iconIPv4 = $ ( "#port-icon-ipv4" ) ;
160- a . textIPv4 = $ ( "#port-ip-text-ipv4" ) ;
161- a . separator = $ ( "#port-ip-separator" ) ;
162- a . iconIPv6 = $ ( "#port-icon-ipv6" ) ;
163- a . textIPv6 = $ ( "#port-ip-text-ipv6" ) ;
164-
165- // If the user has permissions, attach the right-click context menu
166- if ( plugin . canChangeMenu ( ) ) {
167- a . pane . on ( "mousedown" , plugin . createPortMenu ) ;
168- }
115+ a . pane . prop ( "title" , theUILang . checkingPort || "Checking port status..." ) ;
169116
170- // Trigger the initial port check
171- plugin . init ( ) ;
117+ // Trigger the initial port check to get the configuration and build the final UI
118+ theWebUI . request ( "?action=initportcheck" , [ plugin . getPortStatus , plugin ] ) ;
172119} ;
173120
174121// This function is called when the plugin is removed/unloaded
0 commit comments