Przeglądaj źródła

Implement identicon representation for devices.

The first fifteen characters of device IDs are now used to procedurally
generate psuedo-unique avatars for their respective devices. The avatars
are represented using SVG elements that replace the icons previously
shown next to device names in the GUI.
Chris Joel 11 lat temu
rodzic
commit
ac079f0f83
4 zmienionych plików z 105 dodań i 4 usunięć
  1. 65 0
      gui/app.js
  2. 2 3
      gui/index.html
  3. 37 0
      gui/overrides.css
  4. 1 1
      internal/auto/gui.files.go

+ 65 - 0
gui/app.js

@@ -1231,3 +1231,68 @@ syncthing.directive('modal', function () {
         },
     };
 });
+
+syncthing.directive('identicon', ['$window', function ($window) {
+  var svgNS = 'http://www.w3.org/2000/svg';
+
+  function Identicon (value, size) {
+    var svg = document.createElementNS(svgNS, 'svg');
+    var shouldFillRectAt = function (row, col) {
+      return !($window.parseInt(value.charCodeAt(row + col * size), 10) % 2);
+    };
+    var shouldMirrorRectAt = function (row, col) {
+      return !(size % 2 && col === middleCol)
+    };
+    var mirrorColFor = function (col) {
+      return size - col - 1;
+    };
+    var fillRectAt = function (row, col) {
+      var rect = document.createElementNS(svgNS, 'rect');
+
+      rect.setAttribute('x', (col * rectSize) + '%');
+      rect.setAttribute('y', (row * rectSize) + '%');
+      rect.setAttribute('width', rectSize + '%');
+      rect.setAttribute('height', rectSize + '%');
+
+      svg.appendChild(rect);
+    };
+    var rect;
+    var row;
+    var col;
+    var middleCol;
+    var rectSize;
+
+    svg.setAttribute('class', 'identicon');
+    size = size || 5;
+    rectSize = 100 / size;
+    middleCol = Math.ceil(size / 2) - 1;
+
+    if (value) {
+      value = value.toString().replace(/[\W_]/i, '');
+
+      for (row = 0; row < size; ++row) {
+        for (col = middleCol; col > -1; --col) {
+          if (shouldFillRectAt(row, col)) {
+            fillRectAt(row, col);
+
+            if (shouldMirrorRectAt(row, col)) {
+              fillRectAt(row, mirrorColFor(col));
+            }
+          }
+        }
+      }
+    }
+
+    return svg;
+  }
+
+  return {
+    restrict: 'E',
+    scope: {
+      value: '='
+    },
+    link: function (scope, element, attributes) {
+      element.append(new Identicon(scope.value));
+    }
+  }
+}]);

+ 2 - 3
gui/index.html

@@ -190,7 +190,7 @@
         <div class="panel panel-default" ng-repeat="deviceCfg in [thisDevice()]">
           <div class="panel-heading" data-toggle="collapse" href="#device-this" style="cursor: pointer">
             <h3 class="panel-title">
-              <span class="glyphicon glyphicon-home"></span>&emsp;{{deviceName(deviceCfg)}}
+              <identicon data-value="deviceCfg.DeviceID"></identicon>&emsp;{{deviceName(deviceCfg)}}
             </h3>
           </div>
           <div id="device-this" class="panel-collapse collapse in">
@@ -236,7 +236,7 @@
           <div class="panel panel-{{deviceClass(deviceCfg)}}" ng-repeat="deviceCfg in otherDevices()">
             <div class="panel-heading" data-toggle="collapse" data-parent="#devices" href="#device-{{$index}}" style="cursor: pointer">
               <h3 class="panel-title">
-                <span class="glyphicon glyphicon-retweet"></span>&emsp;{{deviceName(deviceCfg)}}
+                <identicon data-value="deviceCfg.DeviceID"></identicon>&emsp;{{deviceName(deviceCfg)}}
                 <span class="pull-right hidden-xs">
                   <span ng-if="connections[deviceCfg.DeviceID] && completion[deviceCfg.DeviceID]._total == 100">
                     <span translate>Up to Date</span> (100%)
@@ -822,7 +822,6 @@
     </ul>
   </modal>
 
-
   <script src="angular/angular.min.js"></script>
   <script src="angular/angular-translate.min.js"></script>
   <script src="angular/angular-translate-loader.min.js"></script>

+ 37 - 0
gui/overrides.css

@@ -28,6 +28,43 @@ ul+h5 {
     margin-top: 1.5em;
 }
 
+identicon {
+  display: inline-block;
+  position: relative;
+  width: 1em;
+  height: 1em;
+  line-height: 1em;
+  overflow: visible;
+}
+
+.identicon {
+    width: 30px;
+    height: 30px;
+}
+
+.identicon rect {
+    opacity: 0.5;
+    fill: #aaa;
+}
+
+.panel-heading .identicon {
+    display: block;
+    position: absolute;
+    top: -4px;
+    left: -9px;
+}
+
+.panel-heading {
+    position: relative;
+    overflow: hidden;
+}
+
+[class*="-info"] .identicon rect,
+[class*="-success"] .identicon rect,
+[class*="-primary"] .identicon rect {
+    fill: #fff;
+}
+
 .text-monospace {
     font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
 }

Plik diff jest za duży
+ 1 - 1
internal/auto/gui.files.go


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików