Browse Source

gui: Add connection status icons to Remote Devices (fixes #8244) (#8553)

Eric P 3 years ago
parent
commit
fd0a6225aa

+ 5 - 0
gui/black/assets/css/theme.css

@@ -273,3 +273,8 @@ code.ng-binding{
 .fancytree-focused {
     background-color: #222;
 }
+
+/* Remote Devices 'connection type'-icon color set to #aaa */
+.reception {
+    filter: invert(77%) sepia(0%) saturate(724%) hue-rotate(146deg) brightness(91%) contrast(85%);
+}

+ 5 - 0
gui/dark/assets/css/theme.css

@@ -285,3 +285,8 @@ code.ng-binding{
 .fancytree-focused {
     background-color: #424242;
 }
+
+/* Remote Devices 'connection type'-icon color set to #aaa */
+.reception {
+    filter: invert(77%) sepia(0%) saturate(724%) hue-rotate(146deg) brightness(91%) contrast(85%);
+}

+ 32 - 0
gui/default/assets/css/overrides.css

@@ -144,6 +144,38 @@ table.table-auto td {
     max-width: 0px;
 }
 
+/* Remote Devices connection-quality indicator */
+.reception-0 {
+    background: url('../../vendor/bootstrap/fonts/reception-0.svg') no-repeat;
+}
+
+.reception-1 {
+    background: url('../../vendor/bootstrap/fonts/reception-1.svg') no-repeat;
+}
+
+.reception-2 {
+    background: url('../../vendor/bootstrap/fonts/reception-2.svg') no-repeat;
+}
+
+.reception-3 {
+    background: url('../../vendor/bootstrap/fonts/reception-3.svg') no-repeat;
+}
+
+.reception-4 {
+    background: url('../../vendor/bootstrap/fonts/reception-4.svg') no-repeat;
+}
+  
+.reception { 
+    width: 1em;
+    height: 1em;
+    display: inline-block;
+    vertical-align: -20%;
+}
+
+.remote-devices-panel {
+    display: inline-block;
+}
+
 /* Wrap long file paths to prevent text overflow. See issue #6268. */
 .file-path {
     word-break: break-all;

+ 26 - 12
gui/default/index.html

@@ -24,6 +24,7 @@
   <link href="assets/css/tree.css" rel="stylesheet"/>
   <link href="assets/css/overrides.css" rel="stylesheet"/>
   <link href="assets/css/theme.css" rel="stylesheet"/>
+  <link href="assets/css/customicons.css" rel="stylesheet"/>
 </head>
 
 <body>
@@ -737,16 +738,25 @@
                 <div class="panel-progress" ng-show="deviceStatus(deviceCfg) == 'syncing'" ng-attr-style="width: {{completion[deviceCfg.deviceID]._total | percent}}"></div>
                 <h4 class="panel-title">
                   <identicon class="panel-icon" data-value="deviceCfg.deviceID"></identicon>
-                  <span ng-switch="deviceStatus(deviceCfg)" class="pull-right text-{{deviceClass(deviceCfg)}}">
-                    <span ng-switch-when="insync"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs" aria-label="{{'Up to Date' | translate}}"><i class="fas fa-fw fa-check"></i></span></span>
-                    <span ng-switch-when="unused-insync"><span class="hidden-xs" translate>Connected (Unused)</span><span class="visible-xs" aria-label="{{'Connected (Unused)' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
-                    <span ng-switch-when="syncing">
-                      <span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.deviceID]._total | percent}}, {{completion[deviceCfg.deviceID]._needBytes | binary}}B)
+                  <span class="pull-right text-{{deviceClass(deviceCfg)}}">
+                    <span ng-switch="deviceStatus(deviceCfg)" class="remote-devices-panel"> 
+                      <span ng-switch-when="insync"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs" aria-label="{{'Up to Date' | translate}}"><i class="fas fa-fw fa-check"></i></span></span>
+                      <span ng-switch-when="unused-insync"><span class="hidden-xs" translate>Connected (Unused)</span><span class="visible-xs" aria-label="{{'Connected (Unused)' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
+                      <span ng-switch-when="syncing">
+                        <span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.deviceID]._total | percent}}, {{completion[deviceCfg.deviceID]._needBytes | binary}}B)
+                      </span>
+                      <span ng-switch-when="paused"><span class="hidden-xs" translate>Paused</span><span class="visible-xs" aria-label="{{'Paused' | translate}}"><i class="fas fa-fw fa-pause"></i></span></span>
+                      <span ng-switch-when="unused-paused"><span class="hidden-xs" translate>Paused (Unused)</span><span class="visible-xs" aria-label="{{'Paused (Unused)' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
+                      <span ng-switch-when="disconnected"><span class="hidden-xs" translate>Disconnected</span><span class="visible-xs" aria-label="{{'Disconnected' | translate}}"><i class="fas fa-fw fa-power-off"></i></span></span>
+                      <span ng-switch-when="unused-disconnected"><span class="hidden-xs" translate>Disconnected (Unused)</span><span class="visible-xs" aria-label="{{'Disconnected (Unused)' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
+                    </span>
+                    <span ng-switch="rdConnType(deviceCfg.deviceID)" class="remote-devices-panel">
+                      <span ng-switch-when="tcplan" class="reception reception-4 reception-theme"></span>
+                      <span ng-switch-when="tcpwan" class="reception reception-3 reception-theme"></span>
+                      <span ng-switch-when="quic" class="reception reception-2 reception-theme"></span> 
+                      <span ng-switch-when="relay" class="reception reception-1 reception-theme"></span>
+                      <span ng-switch-when="disconnected" class="reception reception-0 reception-theme"></span>
                     </span>
-                    <span ng-switch-when="paused"><span class="hidden-xs" translate>Paused</span><span class="visible-xs" aria-label="{{'Paused' | translate}}"><i class="fas fa-fw fa-pause"></i></span></span>
-                    <span ng-switch-when="unused-paused"><span class="hidden-xs" translate>Paused (Unused)</span><span class="visible-xs" aria-label="{{'Paused (Unused)' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
-                    <span ng-switch-when="disconnected"><span class="hidden-xs" translate>Disconnected</span><span class="visible-xs" aria-label="{{'Disconnected' | translate}}"><i class="fas fa-fw fa-power-off"></i></span></span>
-                    <span ng-switch-when="unused-disconnected"><span class="hidden-xs" translate>Disconnected (Unused)</span><span class="visible-xs" aria-label="{{'Disconnected (Unused)' | translate}}"><i class="fas fa-fw fa-unlink"></i></span></span>
                   </span>
                   <div class="panel-title-text">{{deviceName(deviceCfg)}}</div>
                 </h4>
@@ -823,9 +833,13 @@
                           </span>
                         </td>
                       </tr>
-                      <tr ng-if="connections[deviceCfg.deviceID].connected && connections[deviceCfg.deviceID].type.indexOf('Relay') > -1" tooltip data-original-title="Connections via relays might be rate limited by the relay">
-                        <th><span class="fas fa-fw fa-exclamation-triangle text-danger"></span>&nbsp;<span translate>Connection Type</span></th>
-                        <td class="text-right">{{connections[deviceCfg.deviceID].type}}</td>
+                      <tr ng-if="connections[deviceCfg.deviceID].connected">
+                        <th><span class="reception reception-4 reception-theme"></span>&nbsp;<span translate>Connection Type</span></th>
+                        <td ng-if="connections[deviceCfg.deviceID].connected" class="text-right">
+                          <span tooltip data-original-title="{{rdConnDetails(rdConnType(deviceCfg.deviceID))}}">
+                            {{rdConnTypeString(rdConnType(deviceCfg.deviceID))}}
+                          </span>
+                        </td>
                       </tr>
                       <tr ng-if="deviceCfg.allowedNetworks.length > 0">
                         <th><span class="fas fa-fw fa-filter"></span>&nbsp;<span translate>Allowed Networks</span></th>

+ 55 - 0
gui/default/syncthing/core/syncthingController.js

@@ -1192,6 +1192,61 @@ angular.module('syncthing.core')
             return '?';
         };
 
+        $scope.rdConnType = function(deviceID) {
+            var conn = $scope.connections[deviceID];
+            if(!conn)
+                return "-1";
+                
+            if (conn.type.indexOf('relay') === 0)
+                return "relay";
+            
+            if (conn.type.indexOf('quic') === 0)
+                return "quic";
+            
+            if(conn.type.indexOf('tcp') === 0)
+                return "tcp"+rdAddrType(conn.address);
+
+            return "disconnected";
+        }
+
+        function rdAddrType(address) {
+            var re = /(^(?:127\.|0?10\.|172\.0?1[6-9]\.|172\.0?2[0-9]\.|172\.0?3[01]\.|192\.168\.|169\.254\.|::1|[fF][cCdD][0-9a-fA-F]{2}:|[fF][eE][89aAbB][0-9a-fA-F]:))/
+            if(re.test(address)) 
+                return "lan";
+        
+            return "wan";
+        }
+
+        $scope.rdConnTypeString = function(type) {
+            switch (type) {
+                case "relay":
+                    return $translate.instant('Relay');
+                case "quic":
+                    return $translate.instant('QUIC');
+                case "tcpwan":
+                    return $translate.instant('TCP WAN');
+                case "tcplan":
+                    return $translate.instant('TCP LAN');
+                default:
+                    return $translate.instant('Disconnected');
+            }
+        }
+
+        $scope.rdConnDetails = function(type) {
+            switch (type) {
+                case "relay":
+                    return $translate.instant('Connections via relays might be rate limited by the relay');
+                case "quic":
+                    return $translate.instant('QUIC connections are in most cases considered suboptimal');
+                case "tcpwan":
+                    return $translate.instant('Using a direct TCP connection over WAN');
+                case "tcplan":
+                    return $translate.instant('Using a direct TCP connection over LAN');
+                default:
+                    return $translate.instant('Unknown');
+            }
+        }
+
         $scope.hasRemoteGUIAddress = function (deviceCfg) {
             if (!deviceCfg.remoteGUIPort)
                 return false;

+ 3 - 0
gui/default/vendor/bootstrap/fonts/reception-0.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-reception-0" viewBox="0 0 16 16">
+  <path d="M0 13.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z"/>
+</svg>

+ 3 - 0
gui/default/vendor/bootstrap/fonts/reception-1.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-reception-1" viewBox="0 0 16 16">
+  <path d="M0 11.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-2zm4 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z"/>
+</svg>

+ 3 - 0
gui/default/vendor/bootstrap/fonts/reception-2.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-reception-2" viewBox="0 0 16 16">
+  <path d="M0 11.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-2zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-5zm4 5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5zm4 0a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z"/>
+</svg>

+ 3 - 0
gui/default/vendor/bootstrap/fonts/reception-3.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-reception-3" viewBox="0 0 16 16">
+  <path d="M0 11.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-2zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-5zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-8zm4 8a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z"/>
+</svg>

+ 3 - 0
gui/default/vendor/bootstrap/fonts/reception-4.svg

@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-reception-4" viewBox="0 0 16 16">
+  <path d="M0 11.5a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-2zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-5zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-8zm4-3a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 .5.5v11a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1-.5-.5v-11z"/>
+</svg>

+ 5 - 0
gui/light/assets/css/theme.css

@@ -36,3 +36,8 @@
 .fancytree-focused {
     background-color: #eeeeee;
 }
+
+/* Remote Devices 'connection type'-icon color set to #333 */
+.reception {
+    filter: invert(12%) sepia(11%) saturate(20%) hue-rotate(318deg) brightness(100%) contrast(80%);
+}