Browse Source

gui: Refactor to make encryption diff smaller (#7049)

Simon Frei 5 years ago
parent
commit
a20d85d451

+ 3 - 3
gui/default/index.html

@@ -204,10 +204,10 @@
               </div>
               <div class="panel-body">
                 <p>
-                  <span ng-if="pendingFolder.label.length == 0" translate translate-value-device="{{ deviceName(findDevice(device.deviceID)) }}" translate-value-folder="{{ pendingFolder.id }}">
+                  <span ng-if="pendingFolder.label.length == 0" translate translate-value-device="{{ deviceName(devices[device.deviceID]) }}" translate-value-folder="{{ pendingFolder.id }}">
                     {%device%} wants to share folder "{%folder%}".
                   </span>
-                  <span ng-if="pendingFolder.label.length != 0" translate translate-value-device="{{ deviceName(findDevice(device.deviceID)) }}" translate-value-folder="{{ pendingFolder.id }}" translate-value-folderlabel="{{ pendingFolder.label }}">
+                  <span ng-if="pendingFolder.label.length != 0" translate translate-value-device="{{ deviceName(devices[device.deviceID]) }}" translate-value-folder="{{ pendingFolder.id }}" translate-value-folderlabel="{{ pendingFolder.label }}">
                     {%device%} wants to share folder "{%folderlabel%}" ({%folder%}).
                   </span>
                   <span translate ng-if="folders[pendingFolder.id]">Share this folder?</span>
@@ -753,7 +753,7 @@
                     </tr>
                     <tr ng-if="deviceCfg.introducedBy">
                       <th><span class="far fa-fw fa-handshake-o"></span>&nbsp;<span translate>Introduced By</span></th>
-                      <td class="text-right">{{ deviceName(findDevice(deviceCfg.introducedBy)) || deviceCfg.introducedBy.substring(0, 5) }}</td>
+                      <td class="text-right">{{ deviceName(devices[deviceCfg.introducedBy]) || deviceCfg.introducedBy.substring(0, 5) }}</td>
                     </tr>
                     <tr ng-if="connections[deviceCfg.deviceID].clientVersion">
                       <th><span class="fas fa-fw fa-tag"></span>&nbsp;<span translate>Version</span></th>

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

@@ -74,6 +74,15 @@ function deviceMap(l) {
     return m;
 }
 
+function deviceList(m) {
+    var l = [];
+    for (var id in m) {
+        l.push(m[id]);
+    }
+    l.sort(deviceCompare);
+    return l;
+}
+
 function folderMap(l) {
     var m = {};
     l.forEach(function (r) {

+ 85 - 111
gui/default/syncthing/core/syncthingController.js

@@ -27,7 +27,7 @@ angular.module('syncthing.core')
         $scope.errors = [];
         $scope.model = {};
         $scope.myID = '';
-        $scope.devices = [];
+        $scope.devices = {};
         $scope.discoveryCache = {};
         $scope.protocolChanged = false;
         $scope.reportData = {};
@@ -63,9 +63,6 @@ angular.module('syncthing.core')
 
         $scope.folderDefaults = {
             devices: [],
-            sharedDevices: {},
-            selectedDevices: {},
-            unrelatedDevices: {},
             type: "sendreceive",
             rescanIntervalS: 3600,
             fsWatcherDelayS: 10,
@@ -378,15 +375,14 @@ angular.module('syncthing.core')
             $scope.config.options._globalAnnounceServersStr = $scope.config.options.globalAnnounceServers.join(', ');
             $scope.config.options._urAcceptedStr = "" + $scope.config.options.urAccepted;
 
-            $scope.devices = $scope.config.devices;
-            $scope.devices.forEach(function (deviceCfg) {
-                $scope.completion[deviceCfg.deviceID] = {
+            $scope.devices = deviceMap($scope.config.devices);
+            for (var id in $scope.devices) {
+                $scope.completion[id] = {
                     _total: 100,
                     _needBytes: 0,
                     _needItems: 0
                 };
-            });
-            $scope.devices.sort(deviceCompare);
+            };
             $scope.folders = folderMap($scope.config.folders);
             Object.keys($scope.folders).forEach(function (folder) {
                 refreshFolder(folder);
@@ -689,6 +685,14 @@ angular.module('syncthing.core')
             });
         };
 
+        function initShareEditing(editing) {
+            $scope.currentSharing = {};
+            $scope.currentSharing.editing = editing;
+            $scope.currentSharing.shared = [];
+            $scope.currentSharing.unrelated = [];
+            $scope.currentSharing.selected = {};
+        };
+
         $scope.refreshFailed = function (page, perpage) {
             if (!$scope.failed || !$scope.failed.folder) {
                 return;
@@ -1007,11 +1011,11 @@ angular.module('syncthing.core')
             }
 
             // loop through all devices
-            var deviceCount = $scope.devices.length;
+            var deviceCount = 0;
             var pendingFolders = 0;
-            for (var i = 0; i < $scope.devices.length; i++) {
+            for (var id in $scope.devices) {
                 var status = $scope.deviceStatus({
-                    deviceID: $scope.devices[i].deviceID
+                    deviceID: id
                 });
                 switch (status) {
                     case 'unknown':
@@ -1024,7 +1028,8 @@ angular.module('syncthing.core')
                         deviceCount--;
                         break;
                 }
-                pendingFolders += $scope.devices[i].pendingFolders.length;
+                pendingFolders += $scope.devices[id].pendingFolders.length;
+                deviceCount++;
             }
 
             // enumerate notifications
@@ -1061,8 +1066,8 @@ angular.module('syncthing.core')
         };
 
         $scope.friendlyNameFromShort = function (shortID) {
-            var matches = $scope.devices.filter(function (n) {
-                return n.deviceID.substr(0, 7) === shortID;
+            var matches = Object.keys($scope.devices).filter(function (id) {
+                return id.substr(0, 7) === shortID;
             });
             if (matches.length !== 1) {
                 return shortID;
@@ -1071,23 +1076,13 @@ angular.module('syncthing.core')
         };
 
         $scope.friendlyNameFromID = function (deviceID) {
-            var match = $scope.findDevice(deviceID);
+            var match = $scope.devices[deviceID];
             if (match) {
                 return $scope.deviceName(match);
             }
             return deviceID.substr(0, 6);
         };
 
-        $scope.findDevice = function (deviceID) {
-            var matches = $scope.devices.filter(function (n) {
-                return n.deviceID === deviceID;
-            });
-            if (matches.length !== 1) {
-                return undefined;
-            }
-            return matches[0];
-        };
-
         $scope.deviceName = function (deviceCfg) {
             if (typeof deviceCfg === 'undefined' || typeof deviceCfg.deviceID === 'undefined') {
                 return "";
@@ -1110,12 +1105,8 @@ angular.module('syncthing.core')
         };
 
         $scope.setDevicePause = function (device, pause) {
-            $scope.devices.forEach(function (cfg) {
-                if (cfg.deviceID == device) {
-                    cfg.paused = pause;
-                }
-            });
-            $scope.config.devices = $scope.devices;
+            $scope.devices[id].paused = pause;
+            $scope.config.devices = $scope.deviceList();
             $scope.saveConfig();
         };
 
@@ -1344,7 +1335,7 @@ angular.module('syncthing.core')
                 // at it before that and conclude that the settings are
                 // modified (even though we just saved) unless we update
                 // here as well...
-                $scope.devices = $scope.config.devices;
+                $scope.devices = deviceMap($scope.config.devices);
 
                 $scope.saveConfig(function () {
                     if (themeChanged) {
@@ -1410,45 +1401,45 @@ angular.module('syncthing.core')
             $scope.editingExisting = true;
             $scope.willBeReintroducedBy = undefined;
             if (deviceCfg.introducedBy) {
-                var introducerDevice = $scope.findDevice(deviceCfg.introducedBy);
+                var introducerDevice = $scope.devices[deviceCfg.introducedBy];
                 if (introducerDevice && introducerDevice.introducer) {
                     $scope.willBeReintroducedBy = $scope.deviceName(introducerDevice);
                 }
             }
             $scope.currentDevice._addressesStr = deviceCfg.addresses.join(', ');
-            $scope.currentDevice.selectedFolders = {};
+            initShareEditing('device');
+            $scope.currentSharing.selected = {};
             $scope.deviceFolders($scope.currentDevice).forEach(function (folder) {
-                $scope.currentDevice.selectedFolders[folder] = true;
+                $scope.currentSharing.selected[folder] = true;
             });
             $scope.deviceEditor.$setPristine();
             $('#editDevice').modal();
         };
 
-        $scope.selectAllFolders = function () {
-            angular.forEach($scope.folders, function (_, id) {
-                $scope.currentDevice.selectedFolders[id] = true;
-            });
+        $scope.selectAllSharedFolders = function (state) {
+            var devices = $scope.currentSharing.shared;
+            for (var i = 0; i < devices.length; i++) {
+                $scope.currentSharing.selected[devices[i].deviceID] = !!state;
+            }
         };
 
-        $scope.deSelectAllFolders = function () {
-            angular.forEach($scope.folders, function (_, id) {
-                $scope.currentDevice.selectedFolders[id] = false;
-            });
+        $scope.selectAllUnrelatedFolders = function (state) {
+            var devices = $scope.currentSharing.unrelated;
+            for (var i = 0; i < devices.length; i++) {
+                $scope.currentSharing.selected[devices[i].deviceID] = !!state;
+            }
         };
 
         $scope.addDevice = function (deviceID, name) {
             return $http.get(urlbase + '/system/discovery')
                 .success(function (registry) {
                     $scope.discovery = [];
-                    outer:
                     for (var id in registry) {
                         if ($scope.discovery.length === 5) {
                             break;
                         }
-                        for (var i = 0; i < $scope.devices.length; i++) {
-                            if ($scope.devices[i].deviceID === id) {
-                                continue outer;
-                            }
+                        if (id in $scope.devices) {
+                            continue
                         }
                         $scope.discovery.push(id);
                     }
@@ -1460,7 +1451,6 @@ angular.module('syncthing.core')
                         _addressesStr: 'dynamic',
                         compression: 'metadata',
                         introducer: false,
-                        selectedFolders: {},
                         pendingFolders: [],
                         ignoredFolders: []
                     };
@@ -1476,10 +1466,8 @@ angular.module('syncthing.core')
                 return;
             }
 
-            $scope.devices = $scope.devices.filter(function (n) {
-                return n.deviceID !== $scope.currentDevice.deviceID;
-            });
-            $scope.config.devices = $scope.devices;
+            delete $scope.devices[id];
+            $scope.config.devices = $scope.deviceList();
 
             for (var id in $scope.folders) {
                 $scope.folders[id].devices = $scope.folders[id].devices.filter(function (n) {
@@ -1500,23 +1488,11 @@ angular.module('syncthing.core')
                 return x.trim();
             });
 
-            var done = false;
-            for (var i = 0; i < $scope.devices.length && !done; i++) {
-                if ($scope.devices[i].deviceID === deviceCfg.deviceID) {
-                    $scope.devices[i] = deviceCfg;
-                    done = true;
-                }
-            }
+            $scope.devices[deviceCfg.deviceID] = deviceCfg;
+            $scope.config.devices = deviceList($scope.devices);
 
-            if (!done) {
-                $scope.devices.push(deviceCfg);
-            }
-
-            $scope.devices.sort(deviceCompare);
-            $scope.config.devices = $scope.devices;
-
-            for (var id in deviceCfg.selectedFolders) {
-                if (deviceCfg.selectedFolders[id]) {
+            for (var id in $scope.currentSharing.selected) {
+                if ($scope.currentSharing.selected[id]) {
                     var found = false;
                     for (i = 0; i < $scope.folders[id].devices.length; i++) {
                         if ($scope.folders[id].devices[i].deviceID === deviceCfg.deviceID) {
@@ -1574,13 +1550,13 @@ angular.module('syncthing.core')
         };
 
         $scope.otherDevices = function () {
-            return $scope.devices.filter(function (n) {
+            return $scope.deviceList().filter(function (n) {
                 return n.deviceID !== $scope.myID;
             });
         };
 
         $scope.thisDevice = function () {
-            return $scope.thisDeviceIn($scope.devices);
+            return $scope.devices[$scope.myID];
         };
 
         $scope.thisDeviceIn = function (l) {
@@ -1599,16 +1575,16 @@ angular.module('syncthing.core')
         };
 
         $scope.setAllDevicesPause = function (pause) {
-            $scope.devices.forEach(function (cfg) {
-                cfg.paused = pause;
-            });
-            $scope.config.devices = $scope.devices;
+            for (var id in $scope.devices) {
+                $scope.devices[id].paused = pause;
+            };
+            $scope.config.devices = deviceList($scope.devices);
             $scope.saveConfig();
         }
 
         $scope.isAtleastOneDevicePausedStateSetTo = function (pause) {
-            for (var i = 0; i < $scope.devices.length; i++) {
-                if ($scope.devices[i].paused == pause) {
+            for (var id in $scope.devices) {
+                if ($scope.devices[id].paused == pause) {
                     return true;
                 }
             }
@@ -1641,9 +1617,8 @@ angular.module('syncthing.core')
         };
 
         $scope.friendlyDevices = function (str) {
-            for (var i = 0; i < $scope.devices.length; i++) {
-                var cfg = $scope.devices[i];
-                str = str.replace(cfg.deviceID, $scope.deviceName(cfg));
+            for (var id in $scope.devices) {
+                str = str.replace(id, $scope.deviceName($scope.devices[id]));
             }
             return str;
         };
@@ -1652,6 +1627,10 @@ angular.module('syncthing.core')
             return folderList($scope.folders);
         };
 
+        $scope.deviceList = function () {
+            return deviceList($scope.devices);
+        };
+
         $scope.directoryList = [];
 
         $scope.$watch('currentFolder.path', function (newvalue) {
@@ -1724,18 +1703,15 @@ angular.module('syncthing.core')
                 $scope.currentFolder.path = $scope.currentFolder.path.slice(0, -1);
             }
             // Cache complete device objects indexed by ID for lookups
-            var devMap = deviceMap($scope.devices)
-            $scope.currentFolder.sharedDevices = [];
-            $scope.currentFolder.selectedDevices = {};
+            initShareEditing('folder');
             $scope.currentFolder.devices.forEach(function (n) {
                 if (n.deviceID !== $scope.myID) {
-                    $scope.currentFolder.sharedDevices.push(devMap[n.deviceID]);
+                    $scope.currentSharing.shared.push($scope.devices[n.deviceID]);
                 }
-                $scope.currentFolder.selectedDevices[n.deviceID] = true;
+                $scope.currentSharing.selected[n.deviceID] = true;
             });
-            $scope.currentFolder.unrelatedDevices = $scope.devices.filter(function (n) {
-                return n.deviceID !== $scope.myID
-                    && !$scope.currentFolder.selectedDevices[n.deviceID]
+            $scope.currentSharing.unrelated = $scope.deviceList().filter(function (n) {
+                return n.deviceID !== $scope.myID && !$scope.currentSharing.selected[n.deviceID]
             });
             if ($scope.currentFolder.versioning && $scope.currentFolder.versioning.type === "trashcan") {
                 $scope.currentFolder.trashcanFileVersioning = true;
@@ -1795,16 +1771,16 @@ angular.module('syncthing.core')
         };
 
         $scope.selectAllSharedDevices = function (state) {
-            var devices = $scope.currentFolder.sharedDevices;
+            var devices = $scope.currentSharing.shared;
             for (var i = 0; i < devices.length; i++) {
-                $scope.currentFolder.selectedDevices[devices[i].deviceID] = !!state;
+                $scope.currentSharing.selected[devices[i].deviceID] = !!state;
             }
         };
 
         $scope.selectAllUnrelatedDevices = function (state) {
-            var devices = $scope.currentFolder.unrelatedDevices;
+            var devices = $scope.currentSharing.unrelated;
             for (var i = 0; i < devices.length; i++) {
-                $scope.currentFolder.selectedDevices[devices[i].deviceID] = !!state;
+                $scope.currentSharing.selected[devices[i].deviceID] = !!state;
             }
         };
 
@@ -1812,8 +1788,9 @@ angular.module('syncthing.core')
             $http.get(urlbase + '/svc/random/string?length=10').success(function (data) {
                 $scope.editingExisting = false;
                 $scope.currentFolder = angular.copy($scope.folderDefaults);
+                initShareEditing('folder');
                 $scope.currentFolder.id = (data.random.substr(0, 5) + '-' + data.random.substr(5, 5)).toLowerCase();
-                $scope.currentFolder.unrelatedDevices = $scope.otherDevices();
+                $scope.currentSharing.unrelated = $scope.otherDevices();
                 $scope.ignores.text = '';
                 $scope.ignores.error = null;
                 $scope.ignores.disabled = false;
@@ -1829,8 +1806,11 @@ angular.module('syncthing.core')
             $scope.currentFolder.viewFlags = {
                 importFromOtherDevice: true
             };
-            $scope.currentFolder.selectedDevices[device] = true;
-            $scope.currentFolder.unrelatedDevices = $scope.otherDevices();
+            initShareEditing('folder');
+            $scope.currentSharing.selected[device] = true;
+            $scope.currentSharing.unrelated = $scope.deviceList().filter(function (n) {
+                return n.deviceID !== $scope.myID && !$scope.currentSharing.selected[n.deviceID]
+            });
             $scope.ignores.text = '';
             $scope.ignores.error = null;
             $scope.ignores.disabled = false;
@@ -1848,25 +1828,23 @@ angular.module('syncthing.core')
         $scope.saveFolder = function () {
             $('#editFolder').modal('hide');
             var folderCfg = angular.copy($scope.currentFolder);
-            folderCfg.selectedDevices[$scope.myID] = true;
+            $scope.currentSharing.selected[$scope.myID] = true;
             var newDevices = [];
             folderCfg.devices.forEach(function (dev) {
-                if (folderCfg.selectedDevices[dev.deviceID] === true) {
+                if ($scope.currentSharing.selected[dev.deviceID] === true) {
                     newDevices.push(dev);
-                    delete folderCfg.selectedDevices[dev.deviceID];
+                    delete $scope.currentSharing.selected[dev.deviceID];
                 };
             });
-            for (var deviceID in folderCfg.selectedDevices) {
-                if (folderCfg.selectedDevices[deviceID] === true) {
+            for (var deviceID in $scope.currentSharing.selected) {
+                if ($scope.currentSharing.selected[deviceID] === true) {
                     newDevices.push({
                         deviceID: deviceID
                     });
                 }
             }
             folderCfg.devices = newDevices;
-            delete folderCfg.sharedDevices;
-            delete folderCfg.selectedDevices;
-            delete folderCfg.unrelatedDevices;
+            delete $scope.currentSharing;
 
             if (folderCfg.fileVersioningSelector === "trashcan") {
                 folderCfg.versioning = {
@@ -1948,12 +1926,9 @@ angular.module('syncthing.core')
             // Bump time
             pendingFolder.time = (new Date()).toISOString();
 
-            for (var i = 0; i < $scope.devices.length; i++) {
-                if ($scope.devices[i].deviceID == device) {
-                    $scope.devices[i].ignoredFolders.push(pendingFolder);
+            if (id in $scope.devices) {
+                    $scope.devices[id].ignoredFolders.push(pendingFolder);
                     $scope.saveConfig();
-                    return;
-                }
             }
         };
 
@@ -1961,7 +1936,7 @@ angular.module('syncthing.core')
             var names = [];
             folderCfg.devices.forEach(function (device) {
                 if (device.deviceID !== $scope.myID) {
-                    names.push($scope.deviceName($scope.findDevice(device.deviceID)));
+                    names.push($scope.deviceName($scope.devices[device.deviceID]));
                 }
             });
             names.sort();
@@ -2481,7 +2456,6 @@ angular.module('syncthing.core')
         $scope.modalLoaded = function () {
             // once all modal elements have been processed
             if ($('modal').length === 0) {
-
                 // pseudo main. called on all definitions assigned
                 initController();
             }

+ 1 - 4
gui/default/syncthing/core/validDeviceidDirective.js

@@ -16,10 +16,7 @@ angular.module('syncthing.core')
                             }
                         });
                         //Prevents user from adding a duplicate ID
-                        var matches = scope.devices.filter(function (n) {
-                            return n.deviceID == viewValue;
-                        }).length;
-                        if (matches > 0) {
+                        if ($scope.devices.hasOwnProperty(viewValue)) {
                             ctrl.$setValidity('unique', false);
                         } else {
                             ctrl.$setValidity('unique', true);

+ 2 - 2
gui/default/syncthing/device/editDeviceModalView.html

@@ -76,10 +76,10 @@
                   <div class="col-md-4" ng-repeat="folder in folderList()">
                     <div class="checkbox">
                       <label ng-if="folder.label.length == 0">
-                        <input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]">&nbsp;{{folder.id}}
+                        <input type="checkbox" ng-model="currentSharing.selected[folder.id]">&nbsp;{{folder.id}}
                       </label>
                       <label ng-if="folder.label.length != 0">
-                        <input type="checkbox" ng-model="currentDevice.selectedFolders[folder.id]">&nbsp; <span tooltip data-original-title="{{folder.id}}">{{folder.label}}</span>
+                        <input type="checkbox" ng-model="currentSharing.selected[folder.id]">&nbsp; <span tooltip data-original-title="{{folder.id}}">{{folder.label}}</span>
                       </label>
                     </div>
                   </div>

+ 6 - 6
gui/default/syncthing/folder/editFolderModalView.html

@@ -46,7 +46,7 @@
         </div>
 
         <div id="folder-sharing" class="tab-pane">
-          <div class="form-group" ng-if="currentFolder.sharedDevices.length">
+          <div class="form-group" ng-if="currentSharing.shared.length">
             <label translate>Currently Shared With Devices</label>
             <p class="help-block">
               <span translate>Deselect devices to stop sharing this folder with.</span>&emsp;
@@ -54,16 +54,16 @@
                 <a href="#" ng-click="selectAllSharedDevices(false)" translate>Deselect All</a></small>
             </p>
             <div class="row">
-              <div class="col-md-4" ng-repeat="device in currentFolder.sharedDevices">
+              <div class="col-md-4" ng-repeat="device in currentSharing.shared">
                 <div class="checkbox">
                   <label>
-                    <input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]" /> {{deviceName(device)}}
+                    <input type="checkbox" ng-model="currentSharing.selected[device.deviceID]" /> {{deviceName(device)}}
                   </label>
                 </div>
               </div>
             </div>
           </div>
-          <div class="form-group" ng-if="currentFolder.unrelatedDevices.length || otherDevices().length <= 0">
+          <div class="form-group" ng-if="currentSharing.unrelated.length || otherDevices().length <= 0">
             <label translate>Unshared Devices</label>
             <p class="help-block" ng-if="otherDevices().length > 0">
               <span translate>Select additional devices to share this folder with.</span>&emsp;
@@ -74,10 +74,10 @@
               <span translate>There are no devices to share this folder with.</span>
             </p>
             <div class="row">
-              <div class="col-md-4" ng-repeat="device in currentFolder.unrelatedDevices">
+              <div class="col-md-4" ng-repeat="device in currentSharing.unrelated">
                 <div class="checkbox">
                   <label>
-                    <input type="checkbox" ng-model="currentFolder.selectedDevices[device.deviceID]" /> {{deviceName(device)}}
+                    <input type="checkbox" ng-model="currentSharing.selected[device.deviceID]" /> {{deviceName(device)}}
                   </label>
                 </div>
               </div>