1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-25 17:25:16 +03:00

Add paste from clipboard option to VTX tab (#1650)

Add paste from clipboard option to VTX tab
This commit is contained in:
Michael Keller 2019-09-15 00:43:30 +12:00 committed by GitHub
commit dde266a4de
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 172 additions and 25 deletions

View file

@ -5163,6 +5163,14 @@
"message": "<span class=\"message-negative\">Error</span> while loading the VTX Config file", "message": "<span class=\"message-negative\">Error</span> while loading the VTX Config file",
"description": "Message in the GUI log when the VTX Config file is loaded" "description": "Message in the GUI log when the VTX Config file is loaded"
}, },
"vtxLoadClipboardOk": {
"message": "VTX Config info <span class=\"message-positive\">loaded</span> from clipboard",
"description": "Message in the GUI log when the VTX Config file is pasted from clipboard"
},
"vtxLoadClipboardKo": {
"message": "<span class=\"message-negative\">Error</span> while loading the VTX Config info from clipboard. Maybe the contents are not correct",
"description": "Message in the GUI log when the VTX Config file is pasted from clipboard"
},
"vtxButtonSaveFile": { "vtxButtonSaveFile": {
"message": "Save to file", "message": "Save to file",
"description": "Save to file button in the VTX tab" "description": "Save to file button in the VTX tab"
@ -5171,6 +5179,10 @@
"message": "Load from file", "message": "Load from file",
"description": "Load to file button in the VTX tab" "description": "Load to file button in the VTX tab"
}, },
"vtxButtonLoadClipboard": {
"message": "Load from clipboard",
"description": "Paste from clipboard button in the VTX tab"
},
"vtxButtonSave": { "vtxButtonSave": {
"message": "Save", "message": "Save",
"description": "Save button in the VTX tab" "description": "Save button in the VTX tab"

View file

@ -28,6 +28,7 @@
"serial", "serial",
"usb", "usb",
"storage", "storage",
"clipboardRead",
"fileSystem", "fileSystem",
"fileSystem.write", "fileSystem.write",
"fileSystem.retainEntries", "fileSystem.retainEntries",

View file

@ -1152,7 +1152,7 @@ dialog {
/** Hack to change the "display: none" by a "visibility:hidden", to apply /** Hack to change the "display: none" by a "visibility:hidden", to apply
the margin-left: auto needed by the first element to align to the right the buttons */ the margin-left: auto needed by the first element to align to the right the buttons */
.toolbar_fixed_bottom .content_toolbar div[style='display: none;'] { .toolbar_fixed_bottom .content_toolbar div[style='display: none;']:first-child {
visibility: hidden; visibility: hidden;
display: block !important; display: block !important;
} }

111
src/js/Clipboard.js Normal file
View file

@ -0,0 +1,111 @@
'use strict';
/**
* Encapsulates the Clipboard logic, depending on web or nw
*
*/
var Clipboard = {
_nwClipboard: null,
available : null,
readAvailable : null,
writeAvailable : null,
writeText : null,
readText : null
};
Clipboard._configureClipboardAsNwJs = function(nwGui) {
console.log('NW GUI Clipboard available');
this.available = true;
this.readAvailable = true;
this.writeAvailable = true;
this._nwClipboard = nwGui.Clipboard.get();
this.writeText = function(text, onSuccess, onError) {
try {
this._nwClipboard.set(text, "text");
} catch (err) {
if (onError) {
onError(err);
}
}
if (onSuccess) {
onSuccess(text);
}
}
this.readText = function(onSuccess, onError) {
let text = '';
try {
text = this._nwClipboard.get("text");
} catch (err) {
if (onError) {
onError(err);
}
}
if (onSuccess) {
onSuccess(text);
}
}
}
Clipboard._configureClipboardAsChrome = function() {
console.log('Chrome Clipboard available');
this.available = true;
this.readAvailable = false; // FIXME: for some reason the read is not working
this.writeAvailable = true;
this.writeText = function(text, onSuccess, onError) {
navigator.clipboard.writeText(text)
.then(onSuccess)
.catch(onError);
}
this.readText = function(onSuccess, onError) {
navigator.clipboard.readText()
.then(onSuccess)
.catch(onError);
}
}
Clipboard._configureClipboardAsOther = function() {
console.warn('NO Clipboard available');
this.available = false;
this.readAvailable = false;
this.writeAvailable = false;
this.writeText = function(text, onSuccess, onError) {
onError('Clipboard not available');
}
this.readText = function(onSuccess, onError) {
onError('Clipboard not available');
}
}
switch (GUI.Mode) {
case GUI_Modes.NWJS:
Clipboard._configureClipboardAsNwJs(GUI.nwGui);
break;
case GUI_Modes.ChromeApp:
Clipboard._configureClipboardAsChrome();
break;
default:
Clipboard._configureClipboardAsOther();
}

View file

@ -44,7 +44,7 @@ function getCliCommand(command, cliBuffer) {
return commandWithBackSpaces(command, buffer, noOfCharsToDelete); return commandWithBackSpaces(command, buffer, noOfCharsToDelete);
} }
function copyToClipboard(text, nwGui) { function copyToClipboard(text) {
function onCopySuccessful() { function onCopySuccessful() {
const button = $('.tab-cli .copy'); const button = $('.tab-cli .copy');
const origText = button.text(); const origText = button.text();
@ -67,26 +67,10 @@ function copyToClipboard(text, nwGui) {
console.warn(ex); console.warn(ex);
} }
function nwCopy(text) { Clipboard.writeText(text, onCopySuccessful, onCopyFailed);
try {
let clipboard = nwGui.Clipboard.get();
clipboard.set(text, "text");
onCopySuccessful();
} catch (ex) {
onCopyFailed(ex);
}
} }
function webCopy(text) { TABS.cli.initialize = function (callback) {
navigator.clipboard.writeText(text)
.then(onCopySuccessful, onCopyFailed);
}
let copyFunc = nwGui ? nwCopy : webCopy;
copyFunc(text);
}
TABS.cli.initialize = function (callback, nwGui) {
var self = this; var self = this;
if (GUI.active_tab != 'cli') { if (GUI.active_tab != 'cli') {
@ -96,8 +80,6 @@ TABS.cli.initialize = function (callback, nwGui) {
self.outputHistory = ""; self.outputHistory = "";
self.cliBuffer = ""; self.cliBuffer = "";
// nwGui variable is set in main.js
const clipboardCopySupport = !(nwGui == null && !navigator.clipboard);
const enterKeyCode = 13; const enterKeyCode = 13;
function executeCommands(out_string) { function executeCommands(out_string) {
@ -194,9 +176,9 @@ TABS.cli.initialize = function (callback, nwGui) {
$('.tab-cli .window .wrapper').empty(); $('.tab-cli .window .wrapper').empty();
}); });
if (clipboardCopySupport) { if (Clipboard.available) {
$('.tab-cli .copy').click(function() { $('.tab-cli .copy').click(function() {
copyToClipboard(self.outputHistory, nwGui); copyToClipboard(self.outputHistory);
}); });
} else { } else {
$('.tab-cli .copy').hide(); $('.tab-cli .copy').hide();

View file

@ -160,6 +160,9 @@ TABS.vtx.initialize = function (callback) {
$(".vtx_table_not_configured").toggle(vtxTableNotConfigured); $(".vtx_table_not_configured").toggle(vtxTableNotConfigured);
$(".vtx_table_save_pending").toggle(TABS.vtx.vtxTableSavePending); $(".vtx_table_save_pending").toggle(TABS.vtx.vtxTableSavePending);
// Buttons
$('.clipboard_available').toggle(Clipboard.available && Clipboard.readAvailable);
// Insert actual values in the fields // Insert actual values in the fields
// Values of the selected mode // Values of the selected mode
$("#vtx_frequency").val(VTX_CONFIG.vtx_frequency); $("#vtx_frequency").val(VTX_CONFIG.vtx_frequency);
@ -484,6 +487,10 @@ TABS.vtx.initialize = function (callback) {
load_json(); load_json();
}); });
$('a.load_clipboard').click(function () {
load_clipboard_json();
});
$('a.save').click(function () { $('a.save').click(function () {
save_vtx(); save_vtx();
}); });
@ -595,6 +602,36 @@ TABS.vtx.initialize = function (callback) {
}); });
} }
function load_clipboard_json() {
try {
Clipboard.readText(
function(text) {
console.log('Pasted content: ', text);
let vtxConfig = JSON.parse(text);
read_vtx_config_json(vtxConfig, load_html);
TABS.vtx.vtxTableSavePending = true;
console.log('Load VTX clipboard end');
GUI.log(i18n.getMessage('vtxLoadClipboardOk'));
}, function(err) {
GUI.log(i18n.getMessage('vtxLoadClipboardKo'));
console.error('Failed to read clipboard contents: ', err);
}
);
} catch (err) {
console.error('Failed loading VTX file config: ' + err);
GUI.log(i18n.getMessage('vtxLoadClipboardKo'));
}
}
// Save all the values from the tab to MSP // Save all the values from the tab to MSP
function save_vtx() { function save_vtx() {

View file

@ -141,6 +141,7 @@
<script type="text/javascript" src="./js/jenkins_loader.js"></script> <script type="text/javascript" src="./js/jenkins_loader.js"></script>
<script type="text/javascript" src="./js/Analytics.js"></script> <script type="text/javascript" src="./js/Analytics.js"></script>
<script type="text/javascript" src="./js/main.js"></script> <script type="text/javascript" src="./js/main.js"></script>
<script type="text/javascript" src="./js/Clipboard.js"></script>
<script type="text/javascript" src="./js/tabs/static_tab.js"></script> <script type="text/javascript" src="./js/tabs/static_tab.js"></script>
<script type="text/javascript" src="./js/tabs/landing.js"></script> <script type="text/javascript" src="./js/tabs/landing.js"></script>
<script type="text/javascript" src="./js/tabs/setup.js"></script> <script type="text/javascript" src="./js/tabs/setup.js"></script>

View file

@ -271,6 +271,9 @@
<div class="btn load_file_btn"> <div class="btn load_file_btn">
<a class="load_file" id="load_file_button" href="#" i18n="vtxButtonLoadFile"></a> <a class="load_file" id="load_file_button" href="#" i18n="vtxButtonLoadFile"></a>
</div> </div>
<div class="btn load_cliboard_btn clipboard_available">
<a class="load_clipboard" id="load_clipboard_button" href="#" i18n="vtxButtonLoadClipboard"></a>
</div>
<div class="btn save_btn"> <div class="btn save_btn">
<a class="save" id="save_button" href="#" i18n="vtxButtonSave"></a> <a class="save" id="save_button" href="#" i18n="vtxButtonSave"></a>
</div> </div>