Browse Source

gui: Restrict shown decimals and restrict size of header columns (#4973)

Simon Frei 7 years ago
parent
commit
53a029a796

+ 10 - 9
gui/default/index.html

@@ -270,8 +270,8 @@
         <div class="panel-group" id="folders">
           <div class="panel panel-default" ng-repeat="folder in folderList()">
             <button class="btn panel-heading" data-toggle="collapse" data-parent="#folders" data-target="#folder-{{$index}}" aria-expanded="false">
-              <div class="panel-progress" ng-show="folderStatus(folder) == 'syncing'" ng-attr-style="width: {{syncPercentage(folder.id)}}%"></div>
-              <div class="panel-progress" ng-show="folderStatus(folder) == 'scanning' && scanProgress[folder.id] != undefined" ng-attr-style="width: {{scanPercentage(folder.id)}}%"></div>
+              <div class="panel-progress" ng-show="folderStatus(folder) == 'syncing'" ng-attr-style="width: {{syncPercentage(folder.id) | percent}}"></div>
+              <div class="panel-progress" ng-show="folderStatus(folder) == 'scanning' && scanProgress[folder.id] != undefined" ng-attr-style="width: {{scanPercentage(folder.id) | percent}}"></div>
               <h4 class="panel-title">
                 <div class="panel-icon hidden-xs">
                   <span ng-class="[folder.type == 'sendonly' ? 'fas fa-fw fa-lock' : 'fas fa-fw fa-folder']"></span>
@@ -284,14 +284,14 @@
                   <span ng-switch-when="scanning">
                     <span class="hidden-xs" translate>Scanning</span>
                     <span class="hidden-xs" ng-if="scanPercentage(folder.id) != undefined">
-                      ({{scanPercentage(folder.id)}}%)
+                      ({{scanPercentage(folder.id) | percent}})
                     </span>
                     <span class="visible-xs">&#9724;</span>
                   </span>
                   <span ng-switch-when="idle"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs">&#9724;</span></span>
                   <span ng-switch-when="syncing">
                     <span class="hidden-xs" translate>Syncing</span>
-                    <span ng-show="syncRemaining(folder.id)">({{syncPercentage(folder.id)}}%, {{syncRemaining(folder.id) | binary}}B)</span>
+                    <span ng-show="syncRemaining(folder.id)">({{syncPercentage(folder.id) | percent}}, {{syncRemaining(folder.id) | binary}}B)</span>
                   </span>
                   <span ng-switch-when="outofsync"><span class="hidden-xs" translate>Out of Sync</span><span class="visible-xs">&#9724;</span></span>
                 </div>
@@ -334,8 +334,8 @@
                         <span tooltip data-original-title="{{model[folder.id].localFiles | alwaysNumber | localeNumber}} {{'files' | translate}}, {{model[folder.id].localDirectories | alwaysNumber | localeNumber}} {{'directories' | translate}}, ~{{model[folder.id].localBytes | binary}}B">
                           <span class="far fa-copy"></span>&nbsp;{{model[folder.id].localFiles | alwaysNumber | localeNumber}}&ensp;
                           <span class="far fa-folder"></span>&nbsp;{{model[folder.id].localDirectories | alwaysNumber | localeNumber}}&ensp;
-                          <span class="far fa-hdd"></span>&nbsp;~{{model[folder.id].localBytes | binary}}B
-                          <span ng-if="model[folder.id].ignorePatterns"><br/><i><small translate class="text-muted">Reduced by ignore patterns</small></i></span>
+                          <span class="far fa-hdd"></span>&nbsp;~{{model[folder.id].localBytes | binary}}B<!-- get rid of the annoying trailing whitespace
+                          --><span ng-if="model[folder.id].ignorePatterns"><br/><i><small translate class="text-muted">Reduced by ignore patterns</small></i></span>
                         </span>
                       </td>
                     </tr>
@@ -543,7 +543,7 @@
                   </tr>
                   <tr>
                     <th><span class="fas fa-fw fa-tachometer-alt"></span>&nbsp;<span translate>CPU Utilization</span></th>
-                    <td class="text-right">{{system.cpuPercent | alwaysNumber | localeNumber:2}}%</td>
+                    <td class="text-right">{{system.cpuPercent | alwaysNumber | percent}}</td>
                   </tr>
                   <tr>
                     <th><span class="fas fa-fw fa-sitemap"></span>&nbsp;<span translate>Listeners</span></th>
@@ -592,13 +592,13 @@
         <div class="panel-group" id="devices">
           <div class="panel panel-default" ng-repeat="deviceCfg in otherDevices()">
             <button class="btn panel-heading" data-toggle="collapse" data-parent="#devices" data-target="#device-{{$index}}" aria-expanded="false">
-              <div class="panel-progress" ng-show="deviceStatus(deviceCfg) == 'syncing'" ng-attr-style="width: {{completion[deviceCfg.deviceID]._total | number:0}}%"></div>
+              <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">&#9724;</span></span>
                   <span ng-switch-when="syncing">
-                    <span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.deviceID]._total | number:0}}%, {{completion[deviceCfg.deviceID]._needBytes | binary}}B)
+                    <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">&#9724;</span></span>
                   <span ng-switch-when="disconnected"><span class="hidden-xs" translate>Disconnected</span><span class="visible-xs">&#9724;</span></span>
@@ -784,6 +784,7 @@
   <script type="text/javascript" src="syncthing/core/basenameFilter.js"></script>
   <script type="text/javascript" src="syncthing/core/binaryFilter.js"></script>
   <script type="text/javascript" src="syncthing/core/localeNumberFilter.js"></script>
+  <script type="text/javascript" src="syncthing/core/percentFilter.js"></script>
   <script type="text/javascript" src="syncthing/core/durationFilter.js"></script>
   <script type="text/javascript" src="syncthing/core/eventService.js"></script>
   <script type="text/javascript" src="syncthing/core/identiconDirective.js"></script>

+ 49 - 0
gui/default/syncthing/app.js

@@ -195,3 +195,52 @@ function buildTree(children) {
 
     return root.children;
 }
+
+// unitPrefixed converts the input such that it returns a string representation
+// <1000 (<1024) with the metric unit prefix suffixed. I.e. when calling this with
+// binary == true, you need to suffix an additon 'i'.  The "biggest" prefix used
+// is 'T', numbers > 1000T are just returned as such big numbers. If ever deemed
+// useful 'P' can be added easily.
+function unitPrefixed(input, binary) {
+    if (input === undefined || isNaN(input)) {
+        return '0 ';
+    }
+    factor = 1000;
+    i = '';
+    if (binary) {
+        factor = 1024;
+        i = 'i'
+    }
+    if (input > factor * factor * factor * factor * 1000) {
+        // Don't show any decimals for more than 4 digits
+        input /= factor * factor * factor * factor;
+        return input.toLocaleString(undefined, {maximumFractionDigits: 0}) + ' T' + i;
+    }
+    // Show 3 significant digits (e.g. 123T or 2.54T)
+    if (input > factor * factor * factor * factor) {
+        input /= factor * factor * factor * factor;
+        return input.toLocaleString(undefined, {maximumSignificantDigits: 3}) + ' T' + i;
+    }
+    if (input > factor * factor * factor) {
+        input /= factor * factor * factor;
+        if (binary && input >= 1000) {
+            return input.toLocaleString(undefined, {maximumFractionDigits: 0}) + ' G' + i;
+        }
+        return input.toLocaleString(undefined, {maximumSignificantDigits: 3}) + ' G' + i;
+    }
+    if (input > factor * factor) {
+        input /= factor * factor;
+        if (binary && input >= 1000) {
+            return input.toLocaleString(undefined, {maximumFractionDigits: 0}) + ' M' + i;
+        }
+        return input.toLocaleString(undefined, {maximumSignificantDigits: 3}) + ' M' + i;
+    }
+    if (input > factor) {
+        input /= factor;
+        if (binary && input >= 1000) {
+            return input.toLocaleString(undefined, {maximumFractionDigits: 0}) + ' k' + i;
+        }
+        return input.toLocaleString(undefined, {maximumSignificantDigits: 3}) + ' k' + i;
+    }
+    return Math.round(input).toLocaleString() + ' ';
+};

+ 1 - 16
gui/default/syncthing/core/binaryFilter.js

@@ -1,21 +1,6 @@
 angular.module('syncthing.core')
     .filter('binary', function () {
         return function (input) {
-            if (input === undefined || isNaN(input)) {
-                return '0 ';
-            }
-            if (input > 1024 * 1024 * 1024) {
-                input /= 1024 * 1024 * 1024;
-                return input.toLocaleString(undefined, {maximumFractionDigits: 2}) + ' Gi';
-            }
-            if (input > 1024 * 1024) {
-                input /= 1024 * 1024;
-                return input.toLocaleString(undefined, {maximumFractionDigits: 2}) + ' Mi';
-            }
-            if (input > 1024) {
-                input /= 1024;
-                return input.toLocaleString(undefined, {maximumFractionDigits: 2}) + ' Ki';
-            }
-            return Math.round(input).toLocaleString(undefined, {maximumFractionDigits: 2}) + ' ';
+            return unitPrefixed(input, true);
         };
     });

+ 2 - 5
gui/default/syncthing/core/localeNumberFilter.js

@@ -1,9 +1,6 @@
 angular.module('syncthing.core')
     .filter('localeNumber', function () {
-        return function (input, decimals) {
-            if (typeof(decimals) !== 'undefined') {
-                return input.toLocaleString(undefined, {maximumFractionDigits: decimals});
-            }
+        return function (input) {
             return input.toLocaleString();
         };
-    });
+    });

+ 1 - 16
gui/default/syncthing/core/metricFilter.js

@@ -1,21 +1,6 @@
 angular.module('syncthing.core')
     .filter('metric', function () {
         return function (input) {
-            if (input === undefined || isNaN(input)) {
-                return '0 ';
-            }
-            if (input > 1000 * 1000 * 1000) {
-                input /= 1000 * 1000 * 1000;
-                return input.toLocaleString(undefined, {maximumFractionDigits: 2}) + ' G';
-            }
-            if (input > 1000 * 1000) {
-                input /= 1000 * 1000;
-                return input.toLocaleString(undefined, {maximumFractionDigits: 2}) + ' M';
-            }
-            if (input > 1000) {
-                input /= 1000;
-                return input.toLocaleString(undefined, {maximumFractionDigits: 2}) + ' k';
-            }
-            return Math.round(input).toLocaleString(undefined, {maximumFractionDigits: 2}) + ' ';
+            return unitPrefixed(input, false);
         };
     });

+ 15 - 0
gui/default/syncthing/core/percentFilter.js

@@ -0,0 +1,15 @@
+angular.module('syncthing.core')
+    .filter('percent', function () {
+        return function (input) {
+            // Prevent 0.00%
+            if (input === undefined || input < 0.01) {
+                return 0 + '%';
+            }
+            // Hard limit at two decimals
+            if (input < 0.1) {
+                return input.toLocaleString(undefined, {maximumFractionDigits: 2}) + '%';
+            }
+            // "Soft" limit at two significant digits (e.g. 1.2%, not 1.27%)
+            return input.toLocaleString(undefined, {maximumSignificantDigits: 2}) + '%';
+        };
+    });

+ 5 - 5
gui/default/syncthing/transfer/neededFilesModalView.html

@@ -38,11 +38,11 @@
         <td class="col-xs-4">
           <div ng-if="f.type == 'progress' && f.action == 'sync' && progress[neededFolder] && progress[neededFolder][f.name]">
             <div class="progress">
-              <div class="progress-bar progress-bar-success" style="width: {{progress[neededFolder][f.name].reused}}%"></div>
-              <div class="progress-bar" style="width: {{progress[neededFolder][f.name].copiedFromOrigin}}%"></div>
-              <div class="progress-bar progress-bar-info" style="width: {{progress[neededFolder][f.name].copiedFromElsewhere}}%"></div>
-              <div class="progress-bar progress-bar-warning" style="width: {{progress[neededFolder][f.name].pulled}}%"></div>
-              <div class="progress-bar progress-bar-danger progress-bar-striped active" style="width: {{progress[neededFolder][f.name].pulling}}%"></div>
+              <div class="progress-bar progress-bar-success" style="width: {{progress[neededFolder][f.name].reused | percent}}"></div>
+              <div class="progress-bar" style="width: {{progress[neededFolder][f.name].copiedFromOrigin | percent}}"></div>
+              <div class="progress-bar progress-bar-info" style="width: {{progress[neededFolder][f.name].copiedFromElsewhere | percent}}"></div>
+              <div class="progress-bar progress-bar-warning" style="width: {{progress[neededFolder][f.name].pulled | percent}}"></div>
+              <div class="progress-bar progress-bar-danger progress-bar-striped active" style="width: {{progress[neededFolder][f.name].pulling | percent}}"></div>
               <span class="show frontal">
                 {{progress[neededFolder][f.name].bytesDone | binary}}B / {{progress[neededFolder][f.name].bytesTotal | binary}}B
               </span>