|
|
@@ -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();
|
|
|
}
|