mirror of
https://github.com/octoleo/syncthing.git
synced 2024-12-22 10:58:57 +00:00
parent
e5c1948b94
commit
6864f7c9d0
@ -234,6 +234,7 @@
|
||||
"Release Notes": "Release Notes",
|
||||
"Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.": "Release candidates contain the latest features and fixes. They are similar to the traditional bi-weekly Syncthing releases.",
|
||||
"Remote Devices": "Remote Devices",
|
||||
"Remote GUI": "Remote GUI",
|
||||
"Remove": "Remove",
|
||||
"Remove Device": "Remove Device",
|
||||
"Remove Folder": "Remove Folder",
|
||||
|
@ -806,8 +806,8 @@
|
||||
<th><span class="fas fa-fw fa-desktop"></span> <span translate>Remote GUI</span></th>
|
||||
<td class="text-right" ng-attr-title="Port {{deviceCfg.remoteGUIPort}}">
|
||||
<!-- Apply RFC6874 encoding for IPv6 link-local zone identifier -->
|
||||
<a ng-if="idToRemoteGUI[deviceCfg.deviceID]" href="{{idToRemoteGUI[deviceCfg.deviceID].replace('%', '%25')}}">{{idToRemoteGUI[deviceCfg.deviceID]}}</a>
|
||||
<span ng-if="!idToRemoteGUI[deviceCfg.deviceID]">Unreachable</span>
|
||||
<a ng-if="hasRemoteGUIAddress(deviceCfg)" href="{{remoteGUIAddress(deviceCfg).replace('%', '%25')}}">{{remoteGUIAddress(deviceCfg)}}</a>
|
||||
<span translate ng-if="!hasRemoteGUIAddress(deviceCfg)">Unknown</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
@ -24,9 +24,6 @@ angular.module('syncthing.core')
|
||||
$scope.config = {};
|
||||
$scope.configInSync = true;
|
||||
$scope.connections = {};
|
||||
$scope.idToRemoteGUI = {};
|
||||
$scope.remoteGUICache = {};
|
||||
$scope.showRemoteGUI = true;
|
||||
$scope.errors = [];
|
||||
$scope.model = {};
|
||||
$scope.myID = '';
|
||||
@ -64,10 +61,6 @@ angular.module('syncthing.core')
|
||||
$scope.metricRates = (window.localStorage["metricRates"] == "true");
|
||||
} catch (exception) { }
|
||||
|
||||
if ("showRemoteGUI" in window.localStorage) {
|
||||
$scope.showRemoteGUI = (window.localStorage["showRemoteGUI"] == "true");
|
||||
}
|
||||
|
||||
$scope.folderDefaults = {
|
||||
devices: [],
|
||||
type: "sendreceive",
|
||||
@ -382,7 +375,6 @@ angular.module('syncthing.core')
|
||||
$scope.config.options._globalAnnounceServersStr = $scope.config.options.globalAnnounceServers.join(', ');
|
||||
$scope.config.options._urAcceptedStr = "" + $scope.config.options.urAccepted;
|
||||
|
||||
$scope.config.gui["showRemoteGUI"] = $scope.showRemoteGUI;
|
||||
$scope.devices = deviceMap($scope.config.devices);
|
||||
for (var id in $scope.devices) {
|
||||
$scope.completion[id] = {
|
||||
@ -525,16 +517,6 @@ angular.module('syncthing.core')
|
||||
console.log("recalcCompletion", device, $scope.completion[device]);
|
||||
}
|
||||
|
||||
function replaceAddressPort(address, newPort) {
|
||||
var lastColonIndex = address.length;
|
||||
for (var index = 0; index < address.length; index++) {
|
||||
if (address[index] === ":") {
|
||||
lastColonIndex = index;
|
||||
}
|
||||
}
|
||||
return address.substr(0, lastColonIndex) + ":" + newPort.toString();
|
||||
}
|
||||
|
||||
function refreshCompletion(device, folder) {
|
||||
if (device === $scope.myID) {
|
||||
return;
|
||||
@ -581,50 +563,9 @@ angular.module('syncthing.core')
|
||||
}
|
||||
$scope.connections = data;
|
||||
console.log("refreshConnections", data);
|
||||
|
||||
refreshRemoteGUI(data);
|
||||
}).error($scope.emitHTTPError);
|
||||
}
|
||||
|
||||
function refreshRemoteGUI(connections) {
|
||||
if (!$scope.showRemoteGUI) {
|
||||
$scope.idToRemoteGUI = {}
|
||||
return
|
||||
}
|
||||
var newCache = {};
|
||||
for (var id in connections) {
|
||||
if (!(id in $scope.devices)) {
|
||||
// Avoid errors when called before first updateLocalConfig()
|
||||
continue;
|
||||
}
|
||||
var port = $scope.devices[id].remoteGUIPort;
|
||||
if (port <= 0
|
||||
|| !connections[id].address
|
||||
|| connections[id].type.includes("relay")) {
|
||||
// Relay connections never work as desired here, nor incomplete addresses
|
||||
$scope.idToRemoteGUI[id] = "";
|
||||
continue;
|
||||
}
|
||||
var newAddress = "http://" + replaceAddressPort(connections[id].address, port);
|
||||
if (!(newAddress in $scope.remoteGUICache)) {
|
||||
// No cached result, trigger a new port probing asynchronously
|
||||
$scope.probeRemoteGUIAddress(id, newAddress);
|
||||
} else {
|
||||
newCache[newAddress] = $scope.remoteGUICache[newAddress];
|
||||
// Copy cached probing result in the corner case of duplicate GUI
|
||||
// addresses for different devices. Which is useless, but
|
||||
// possible when behind the same NAT router.
|
||||
if (newCache[newAddress]) {
|
||||
$scope.idToRemoteGUI[id] = newAddress;
|
||||
} else {
|
||||
$scope.idToRemoteGUI[id] = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
// Replace the cache to discard stale addresses
|
||||
$scope.remoteGUICache = newCache;
|
||||
}
|
||||
|
||||
function refreshErrors() {
|
||||
$http.get(urlbase + '/system/error').success(function (data) {
|
||||
$scope.errors = data.errors;
|
||||
@ -643,22 +584,6 @@ angular.module('syncthing.core')
|
||||
}).error($scope.emitHTTPError);
|
||||
}
|
||||
|
||||
$scope.probeRemoteGUIAddress = function (deviceId, address) {
|
||||
// Strip off possible IPv6 link-local zone identifier, as Angular chokes on it
|
||||
// with an (ugly, unjustified) console error message.
|
||||
var urlAddress = address.replace(/%[a-zA-Z0-9_\.\-]*\]/, ']');
|
||||
$http({
|
||||
method: "OPTIONS",
|
||||
url: urlAddress,
|
||||
}).success(function (data) {
|
||||
$scope.remoteGUICache[address] = true;
|
||||
$scope.idToRemoteGUI[deviceId] = address;
|
||||
}).error(function (err) {
|
||||
$scope.remoteGUICache[address] = false;
|
||||
$scope.idToRemoteGUI[deviceId] = "";
|
||||
});
|
||||
}
|
||||
|
||||
$scope.refreshNeed = function (page, perpage) {
|
||||
if (!$scope.neededFolder) {
|
||||
return;
|
||||
@ -1140,6 +1065,28 @@ angular.module('syncthing.core')
|
||||
return '?';
|
||||
};
|
||||
|
||||
$scope.hasRemoteGUIAddress = function (deviceCfg) {
|
||||
if (!deviceCfg.remoteGUIPort)
|
||||
return false;
|
||||
var conn = $scope.connections[deviceCfg.deviceID];
|
||||
return conn && conn.connected && conn.address && conn.type.indexOf('Relay') == -1;
|
||||
};
|
||||
|
||||
$scope.remoteGUIAddress = function (deviceCfg) {
|
||||
// Assume hasRemoteGUIAddress is true or we would not be here
|
||||
var conn = $scope.connections[deviceCfg.deviceID];
|
||||
return 'http://' + replaceAddressPort(conn.address, deviceCfg.remoteGUIPort);
|
||||
};
|
||||
|
||||
function replaceAddressPort(address, newPort) {
|
||||
for (var index = address.length - 1; index >= 0; index--) {
|
||||
if (address[index] === ":") {
|
||||
return address.substr(0, index) + ":" + newPort.toString();
|
||||
}
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
$scope.friendlyNameFromShort = function (shortID) {
|
||||
var matches = Object.keys($scope.devices).filter(function (id) {
|
||||
return id.substr(0, 7) === shortID;
|
||||
@ -1317,11 +1264,6 @@ angular.module('syncthing.core')
|
||||
};
|
||||
|
||||
$scope.saveConfig = function (callback) {
|
||||
// set local storage feature and delete from post request
|
||||
window.localStorage.setItem("showRemoteGUI", $scope.config.gui.showRemoteGUI ? "true" : "false");
|
||||
$scope.showRemoteGUI = $scope.config.gui.showRemoteGUI;
|
||||
delete $scope.config.gui.showRemoteGUI;
|
||||
|
||||
var cfg = JSON.stringify($scope.config);
|
||||
var opts = {
|
||||
headers: {
|
||||
|
@ -815,12 +815,12 @@
|
||||
<td class="text-right" ng-attr-title="{{deviceFolders(deviceCfg).map(folderLabel).join(', ')}}">{{deviceFolders(deviceCfg).map(folderLabel).join(", ")}}</td>
|
||||
</tr>
|
||||
<tr ng-if="deviceCfg.remoteGUIPort > 0">
|
||||
<th><span class="fas fa-fw fa-desktop"></span> <span translate>Remote GUI</span></th>
|
||||
<td class="text-right" ng-attr-title="Port {{deviceCfg.remoteGUIPort}}">
|
||||
<th><span class="fas fa-fw fa-desktop"></span> <span translate>Remote GUI</span></th>
|
||||
<td class="text-right" ng-attr-title="Port {{deviceCfg.remoteGUIPort}}">
|
||||
<!-- Apply RFC6874 encoding for IPv6 link-local zone identifier -->
|
||||
<a ng-if="idToRemoteGUI[deviceCfg.deviceID]" href="{{idToRemoteGUI[deviceCfg.deviceID].replace('%', '%25')}}">{{idToRemoteGUI[deviceCfg.deviceID]}}</a>
|
||||
<span ng-if="!idToRemoteGUI[deviceCfg.deviceID]">Unreachable</span>
|
||||
</td>
|
||||
<a ng-if="hasRemoteGUIAddress(deviceCfg)" href="{{remoteGUIAddress(deviceCfg).replace('%', '%25')}}">{{remoteGUIAddress(deviceCfg)}}</a>
|
||||
<span translate ng-if="!hasRemoteGUIAddress(deviceCfg)">Unknown</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -24,9 +24,6 @@ angular.module('syncthing.core')
|
||||
$scope.config = {};
|
||||
$scope.configInSync = true;
|
||||
$scope.connections = {};
|
||||
$scope.idToRemoteGUI = {};
|
||||
$scope.remoteGUICache = {};
|
||||
$scope.showRemoteGUI = true;
|
||||
$scope.errors = [];
|
||||
$scope.model = {};
|
||||
$scope.myID = '';
|
||||
@ -64,10 +61,6 @@ angular.module('syncthing.core')
|
||||
$scope.metricRates = (window.localStorage["metricRates"] == "true");
|
||||
} catch (exception) { }
|
||||
|
||||
if ("showRemoteGUI" in window.localStorage) {
|
||||
$scope.showRemoteGUI = (window.localStorage["showRemoteGUI"] == "true");
|
||||
}
|
||||
|
||||
$scope.folderDefaults = {
|
||||
devices: [],
|
||||
type: "sendreceive",
|
||||
@ -382,7 +375,6 @@ angular.module('syncthing.core')
|
||||
$scope.config.options._globalAnnounceServersStr = $scope.config.options.globalAnnounceServers.join(', ');
|
||||
$scope.config.options._urAcceptedStr = "" + $scope.config.options.urAccepted;
|
||||
|
||||
$scope.config.gui["showRemoteGUI"] = $scope.showRemoteGUI;
|
||||
$scope.devices = deviceMap($scope.config.devices);
|
||||
for (var id in $scope.devices) {
|
||||
$scope.completion[id] = {
|
||||
@ -525,16 +517,6 @@ angular.module('syncthing.core')
|
||||
console.log("recalcCompletion", device, $scope.completion[device]);
|
||||
}
|
||||
|
||||
function replaceAddressPort(address, newPort) {
|
||||
var lastColonIndex = address.length;
|
||||
for (var index = 0; index < address.length; index++) {
|
||||
if (address[index] === ":") {
|
||||
lastColonIndex = index;
|
||||
}
|
||||
}
|
||||
return address.substr(0, lastColonIndex) + ":" + newPort.toString();
|
||||
}
|
||||
|
||||
function refreshCompletion(device, folder) {
|
||||
if (device === $scope.myID) {
|
||||
return;
|
||||
@ -581,50 +563,9 @@ angular.module('syncthing.core')
|
||||
}
|
||||
$scope.connections = data;
|
||||
console.log("refreshConnections", data);
|
||||
|
||||
refreshRemoteGUI(data);
|
||||
}).error($scope.emitHTTPError);
|
||||
}
|
||||
|
||||
function refreshRemoteGUI(connections) {
|
||||
if (!$scope.showRemoteGUI) {
|
||||
$scope.idToRemoteGUI = {}
|
||||
return
|
||||
}
|
||||
var newCache = {};
|
||||
for (var id in connections) {
|
||||
if (!(id in $scope.devices)) {
|
||||
// Avoid errors when called before first updateLocalConfig()
|
||||
continue;
|
||||
}
|
||||
var port = $scope.devices[id].remoteGUIPort;
|
||||
if (port <= 0
|
||||
|| !connections[id].address
|
||||
|| connections[id].type.includes("relay")) {
|
||||
// Relay connections never work as desired here, nor incomplete addresses
|
||||
$scope.idToRemoteGUI[id] = "";
|
||||
continue;
|
||||
}
|
||||
var newAddress = "http://" + replaceAddressPort(connections[id].address, port);
|
||||
if (!(newAddress in $scope.remoteGUICache)) {
|
||||
// No cached result, trigger a new port probing asynchronously
|
||||
$scope.probeRemoteGUIAddress(id, newAddress);
|
||||
} else {
|
||||
newCache[newAddress] = $scope.remoteGUICache[newAddress];
|
||||
// Copy cached probing result in the corner case of duplicate GUI
|
||||
// addresses for different devices. Which is useless, but
|
||||
// possible when behind the same NAT router.
|
||||
if (newCache[newAddress]) {
|
||||
$scope.idToRemoteGUI[id] = newAddress;
|
||||
} else {
|
||||
$scope.idToRemoteGUI[id] = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
// Replace the cache to discard stale addresses
|
||||
$scope.remoteGUICache = newCache;
|
||||
}
|
||||
|
||||
function refreshErrors() {
|
||||
$http.get(urlbase + '/system/error').success(function (data) {
|
||||
$scope.errors = data.errors;
|
||||
@ -643,23 +584,6 @@ angular.module('syncthing.core')
|
||||
}).error($scope.emitHTTPError);
|
||||
}
|
||||
|
||||
$scope.probeRemoteGUIAddress = function (deviceId, address) {
|
||||
// Strip off possible IPv6 link-local zone identifier, as Angular chokes on it
|
||||
// with an (ugly, unjustified) console error message.
|
||||
var urlAddress = address.replace(/%[a-zA-Z0-9_\.\-]*\]/, ']');
|
||||
console.log(urlAddress);
|
||||
$http({
|
||||
method: "OPTIONS",
|
||||
url: urlAddress,
|
||||
}).success(function (data) {
|
||||
$scope.remoteGUICache[address] = true;
|
||||
$scope.idToRemoteGUI[deviceId] = address;
|
||||
}).error(function (err) {
|
||||
$scope.remoteGUICache[address] = false;
|
||||
$scope.idToRemoteGUI[deviceId] = "";
|
||||
});
|
||||
}
|
||||
|
||||
$scope.refreshNeed = function (page, perpage) {
|
||||
if (!$scope.neededFolder) {
|
||||
return;
|
||||
@ -1145,6 +1069,28 @@ angular.module('syncthing.core')
|
||||
return '?';
|
||||
};
|
||||
|
||||
$scope.hasRemoteGUIAddress = function (deviceCfg) {
|
||||
if (!deviceCfg.remoteGUIPort)
|
||||
return false;
|
||||
var conn = $scope.connections[deviceCfg.deviceID];
|
||||
return conn && conn.connected && conn.address && conn.type.indexOf('Relay') == -1;
|
||||
};
|
||||
|
||||
$scope.remoteGUIAddress = function (deviceCfg) {
|
||||
// Assume hasRemoteGUIAddress is true or we would not be here
|
||||
var conn = $scope.connections[deviceCfg.deviceID];
|
||||
return 'http://' + replaceAddressPort(conn.address, deviceCfg.remoteGUIPort);
|
||||
};
|
||||
|
||||
function replaceAddressPort(address, newPort) {
|
||||
for (var index = address.length - 1; index >= 0; index--) {
|
||||
if (address[index] === ":") {
|
||||
return address.substr(0, index) + ":" + newPort.toString();
|
||||
}
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
$scope.friendlyNameFromShort = function (shortID) {
|
||||
var matches = Object.keys($scope.devices).filter(function (id) {
|
||||
return id.substr(0, 7) === shortID;
|
||||
@ -1322,11 +1268,6 @@ angular.module('syncthing.core')
|
||||
};
|
||||
|
||||
$scope.saveConfig = function (callback) {
|
||||
// set local storage feature and delete from post request
|
||||
window.localStorage.setItem("showRemoteGUI", $scope.config.gui.showRemoteGUI ? "true" : "false");
|
||||
$scope.showRemoteGUI = $scope.config.gui.showRemoteGUI;
|
||||
delete $scope.config.gui.showRemoteGUI;
|
||||
|
||||
var cfg = JSON.stringify($scope.config);
|
||||
var opts = {
|
||||
headers: {
|
||||
|
Loading…
Reference in New Issue
Block a user