* gui: Use discovered IDs from cache when adding a new remote device. The GUI already does refreshDiscoveryCache() when it comes online and on every 10 second refresh cycle. Querying the same information freshly in addDevice() seems unnecessary and adds some more round-trip delay on a possibly slow network link. Instead use the IDs from the existing discoveryCache property to populate the suggested ID list. * Increase maximum suggested device ID count to 100. For the auto-completion list, which is hidden by default and filtered by the browser, we can offer more discovered device IDs without causing much confusion. The list of suggested "nearby" devices is still limited to the first five. * Rename $scope.discoveryUnknown. The old name "discovery" was pretty ambiguous..
181 lines
12 KiB
HTML
181 lines
12 KiB
HTML
<modal id="editDevice" status="default" icon="{{editDeviceModalIcon()}}" heading="{{editDeviceModalTitle()}}" large="yes" closeable="yes">
|
|
<div class="modal-body">
|
|
<form role="form" name="deviceEditor">
|
|
<ul class="nav nav-tabs" ng-init="loadFormIntoScope(deviceEditor)">
|
|
<li class="active"><a data-toggle="tab" href="#device-general"><span class="fas fa-cog"></span> <span translate>General</span></a></li>
|
|
<li ng-if="!editingDeviceDefaults()"><a data-toggle="tab" href="#device-sharing"><span class="fas fa-share-alt"></span> <span translate>Sharing</span></a></li>
|
|
<li><a data-toggle="tab" href="#device-advanced"><span class="fas fa-cogs"></span> <span translate>Advanced</span></a></li>
|
|
</ul>
|
|
<div class="tab-content">
|
|
<div id="device-general" class="tab-pane in active">
|
|
<div ng-if="!editingDeviceDefaults()" class="form-group" ng-class="{'has-error': deviceEditor.deviceID.$invalid && deviceEditor.deviceID.$dirty}" ng-init="loadFormIntoScope(deviceEditor)">
|
|
<label translate for="deviceID">Device ID</label>
|
|
<div class="input-group">
|
|
<input ng-if="editingDeviceNew()" name="deviceID" id="deviceID" class="form-control text-monospace" type="text" ng-model="currentDevice.deviceID" required="" valid-deviceid list="discovery-list" aria-required="true" />
|
|
<div ng-if="!editingDeviceNew()" class="well well-sm form-control text-monospace" style="height: auto;" select-on-click>{{currentDevice.deviceID}}</div>
|
|
<div class="input-group-btn">
|
|
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#idqr" ng-disabled="editingDeviceNew() && !deviceEditor.deviceID.$valid">
|
|
<span class="fas fa-qrcode"></span> <span translate>Show QR</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div ng-if="editingDeviceNew()">
|
|
<datalist id="discovery-list">
|
|
<option ng-repeat="id in discoveryUnknown" value="{{id}}" />
|
|
</datalist>
|
|
<div class="help-block" ng-if="discoveryUnknown && discoveryUnknown.length !== 0">
|
|
<span translate>You can also select one of these nearby devices:</span>
|
|
<ul>
|
|
<li ng-repeat="id in discoveryUnknown.slice(0, 5)" style="list-style-type: none;">
|
|
<a href="#" ng-click="currentDevice.deviceID = id">
|
|
<identicon data-value="id"></identicon> {{id}}
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<p class="help-block">
|
|
<span translate ng-if="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">The device ID to enter here can be found in the "Actions > Show ID" dialog on the other device. Spaces and dashes are optional (ignored).</span>
|
|
<span translate ng-show="deviceEditor.deviceID.$valid || deviceEditor.deviceID.$pristine">When adding a new device, keep in mind that this device must be added on the other side too.</span>
|
|
<span translate ng-if="deviceEditor.deviceID.$error.required && deviceEditor.deviceID.$dirty">The device ID cannot be blank.</span>
|
|
<span translate ng-if="deviceEditor.deviceID.$error.validDeviceid && deviceEditor.deviceID.$dirty">The entered device ID does not look valid. It should be a 52 or 56 character string consisting of letters and numbers, with spaces and dashes being optional.</span>
|
|
<span translate ng-if="deviceEditor.deviceID.$error.unique && deviceEditor.deviceID.$dirty">A device with that ID is already added.</span>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label translate for="name">Device Name</label>
|
|
<input id="name" class="form-control" type="text" ng-model="currentDevice.name" />
|
|
<p translate ng-if="currentDevice.deviceID == myID" class="help-block">Shown instead of Device ID in the cluster status. Will be advertised to other devices as an optional default name.</p>
|
|
<p translate ng-if="currentDevice.deviceID != myID" class="help-block">Shown instead of Device ID in the cluster status. Will be updated to the name the device advertises if left empty.</p>
|
|
</div>
|
|
</div>
|
|
<div ng-if="!editingDeviceDefaults()" id="device-sharing" class="tab-pane">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="currentDevice.introducer">
|
|
<span translate>Introducer</span>
|
|
<p translate class="help-block">Add devices from the introducer to our device list, for mutually shared folders.</p>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<div class="checkbox">
|
|
<label>
|
|
<input type="checkbox" ng-model="currentDevice.autoAcceptFolders">
|
|
<span translate>Auto Accept</span>
|
|
<p translate class="help-block">Automatically create or share folders that this device advertises at the default path.</p>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<div class="form-horizontal" ng-if="currentSharing.shared.length">
|
|
<label translate for="folders">Shared Folders</label>
|
|
<p class="help-block">
|
|
<span translate>Deselect folders to stop sharing with this device.</span> 
|
|
<small><a href="#" ng-click="selectAllSharedFolders(true)" translate>Select All</a> 
|
|
<a href="#" ng-click="selectAllSharedFolders(false)" translate>Deselect All</a></small>
|
|
</p>
|
|
<div class="form-group" ng-repeat="folder in currentSharing.shared">
|
|
<share-template selected="currentSharing.selected" encryption-passwords="currentSharing.encryptionPasswords" id="{{folder.id}}" label="{{folderLabelMarkRemoteState(folder.id, currentDevice.deviceID)}}" folder-type="{{folder.type}}" untrusted="currentDevice.untrusted" />
|
|
</div>
|
|
<p class="help-block" ng-if="deviceHasUnacceptedFolders(currentDevice)">
|
|
<sup>1</sup> <span translate>The remote device has not accepted sharing this folder.</span>
|
|
</p>
|
|
<p class="help-block" ng-if="deviceHasPausedFolders(currentDevice)">
|
|
<sup>2</sup> <span translate>The remote device has paused this folder.</span>
|
|
</p>
|
|
</div>
|
|
<div class="form-horizontal" ng-if="currentSharing.unrelated.length">
|
|
<label translate for="folders">Unshared Folders</label>
|
|
<p class="help-block" ng-if="folderList().length > 0">
|
|
<span translate>Select additional folders to share with this device.</span> 
|
|
<small><a href="#" ng-click="selectAllUnrelatedFolders(true)" translate>Select All</a> 
|
|
<a href="#" ng-click="selectAllUnrelatedFolders(false)" translate>Deselect All</a></small>
|
|
</p>
|
|
<p class="help-block" ng-if="folderList().length == 0">
|
|
<span translate>There are no folders to share with this device.</span>
|
|
</p>
|
|
<div class="form-group" ng-repeat="folder in currentSharing.unrelated">
|
|
<share-template selected="currentSharing.selected" encryption-passwords="currentSharing.encryptionPasswords" id="{{folder.id}}" label="{{folderLabel(folder.id)}}" folder-type="{{folder.type}}" untrusted="currentDevice.untrusted" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="device-advanced" class="tab-pane">
|
|
<div class="row form-group">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label translate for="addresses">Addresses</label>
|
|
<input ng-disabled="currentDevice.deviceID == myID" id="addresses" class="form-control" type="text" ng-model="currentDevice._addressesStr"></input>
|
|
<p translate class="help-block">Enter comma separated ("tcp://ip:port", "tcp://host:port") addresses or "dynamic" to perform automatic discovery of the address.</p>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label translate>Compression</label>
|
|
<select class="form-control" ng-model="currentDevice.compression">
|
|
<option value="always" translate>All Data</option>
|
|
<option value="metadata" translate>Metadata Only</option>
|
|
<option value="never" translate>Off</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row form-group">
|
|
<div class="col-md-12">
|
|
<label translate>Device rate limits</label>
|
|
<div class="row">
|
|
<div class="col-md-6" ng-class="{'has-error': deviceEditor.maxRecvKbps.$invalid && deviceEditor.maxRecvKbps.$dirty}">
|
|
<div class="row">
|
|
<span class="col-md-8" translate>Incoming Rate Limit (KiB/s)</span>
|
|
<div class="col-md-4">
|
|
<input name="maxRecvKbps" id="maxRecvKbps" class="form-control" type="number" pattern="\d+" ng-model="currentDevice.maxRecvKbps" min="0" />
|
|
</div>
|
|
</div>
|
|
<p class="help-block" ng-if="!deviceEditor.maxRecvKbps.$valid && deviceEditor.maxRecvKbps.$dirty" translate>The rate limit must be a non-negative number (0: no limit)</p>
|
|
</div>
|
|
<div class="col-md-6" ng-class="{'has-error': deviceEditor.maxSendKbps.$invalid && deviceEditor.maxSendKbps.$dirty}">
|
|
<div class="row">
|
|
<span class="col-md-8" translate>Outgoing Rate Limit (KiB/s)</span>
|
|
<div class="col-md-4">
|
|
<input name="maxSendKbps" id="maxSendKbps" class="form-control" type="number" pattern="\d+" ng-model="currentDevice.maxSendKbps" min="0" />
|
|
</div>
|
|
</div>
|
|
<p class="help-block" ng-if="!deviceEditor.maxSendKbps.$valid && deviceEditor.maxSendKbps.$dirty" translate>The rate limit must be a non-negative number (0: no limit)</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="form-group col-md-6">
|
|
<input type="checkbox" id="untrusted" ng-model="currentDevice.untrusted" />
|
|
<label for="untrusted" translate>Untrusted</label>
|
|
<p translate class="help-block">All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-primary btn-sm" ng-click="saveDevice()" ng-disabled="deviceEditor.$invalid">
|
|
<span class="fas fa-check"></span> <span translate>Save</span>
|
|
</button>
|
|
<button type="button" class="btn btn-default btn-sm" data-dismiss="modal">
|
|
<span class="fas fa-times"></span> <span translate>Close</span>
|
|
</button>
|
|
<div ng-if="editingDeviceExisting()" class="pull-left">
|
|
<button type="button" class="btn btn-warning btn-sm" data-toggle="modal" data-target="#remove-device-confirmation">
|
|
<span class="fas fa-minus-circle"></span> <span translate>Remove</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</modal>
|