implement dialog to import personal bookmarks
This commit is contained in:
parent
620ba11565
commit
2d142e45ed
@ -80,7 +80,7 @@ h1 {
|
|||||||
padding-right: 15px;
|
padding-right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bookmarks table .frequency {
|
.bookmarks table .frequency, .bookmark-list table .frequency {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +90,10 @@ h1 {
|
|||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bookmark-list table .form-check-input {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.actions {
|
.actions {
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
}
|
}
|
||||||
|
@ -145,21 +145,3 @@ BookmarkBar.prototype.getDemodulatorPanel = function() {
|
|||||||
BookmarkBar.prototype.getDemodulator = function() {
|
BookmarkBar.prototype.getDemodulator = function() {
|
||||||
return this.getDemodulatorPanel().getDemodulator();
|
return this.getDemodulatorPanel().getDemodulator();
|
||||||
};
|
};
|
||||||
|
|
||||||
BookmarkLocalStorage = function(){
|
|
||||||
};
|
|
||||||
|
|
||||||
BookmarkLocalStorage.prototype.getBookmarks = function(){
|
|
||||||
return JSON.parse(window.localStorage.getItem("bookmarks")) || [];
|
|
||||||
};
|
|
||||||
|
|
||||||
BookmarkLocalStorage.prototype.setBookmarks = function(bookmarks){
|
|
||||||
window.localStorage.setItem("bookmarks", JSON.stringify(bookmarks));
|
|
||||||
};
|
|
||||||
|
|
||||||
BookmarkLocalStorage.prototype.deleteBookmark = function(data) {
|
|
||||||
if (data.id) data = data.id;
|
|
||||||
var bookmarks = this.getBookmarks();
|
|
||||||
bookmarks = bookmarks.filter(function(b) { return b.id !== data; });
|
|
||||||
this.setBookmarks(bookmarks);
|
|
||||||
};
|
|
||||||
|
17
htdocs/lib/BookmarkLocalStorage.js
Normal file
17
htdocs/lib/BookmarkLocalStorage.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
BookmarkLocalStorage = function(){
|
||||||
|
};
|
||||||
|
|
||||||
|
BookmarkLocalStorage.prototype.getBookmarks = function(){
|
||||||
|
return JSON.parse(window.localStorage.getItem("bookmarks")) || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
BookmarkLocalStorage.prototype.setBookmarks = function(bookmarks){
|
||||||
|
window.localStorage.setItem("bookmarks", JSON.stringify(bookmarks));
|
||||||
|
};
|
||||||
|
|
||||||
|
BookmarkLocalStorage.prototype.deleteBookmark = function(data) {
|
||||||
|
if (data.id) data = data.id;
|
||||||
|
var bookmarks = this.getBookmarks();
|
||||||
|
bookmarks = bookmarks.filter(function(b) { return b.id !== data; });
|
||||||
|
this.setBookmarks(bookmarks);
|
||||||
|
};
|
@ -66,14 +66,16 @@ NameEditor.prototype.getInputHtml = function() {
|
|||||||
|
|
||||||
function FrequencyEditor(table) {
|
function FrequencyEditor(table) {
|
||||||
Editor.call(this, table);
|
Editor.call(this, table);
|
||||||
this.suffixes = {
|
|
||||||
'K': 3,
|
|
||||||
'M': 6,
|
|
||||||
'G': 9,
|
|
||||||
'T': 12
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FrequencyEditor.suffixes = {
|
||||||
|
'': 0,
|
||||||
|
'K': 3,
|
||||||
|
'M': 6,
|
||||||
|
'G': 9,
|
||||||
|
'T': 12
|
||||||
|
};
|
||||||
|
|
||||||
FrequencyEditor.prototype = new Editor();
|
FrequencyEditor.prototype = new Editor();
|
||||||
|
|
||||||
FrequencyEditor.prototype.getInputHtml = function() {
|
FrequencyEditor.prototype.getInputHtml = function() {
|
||||||
@ -81,8 +83,7 @@ FrequencyEditor.prototype.getInputHtml = function() {
|
|||||||
'<input class="form-control form-control-sm" type="number" step="1">' +
|
'<input class="form-control form-control-sm" type="number" step="1">' +
|
||||||
'<div class="input-group-append">' +
|
'<div class="input-group-append">' +
|
||||||
'<select class="input-group-text exponent">' +
|
'<select class="input-group-text exponent">' +
|
||||||
'<option value="0">Hz</option>' +
|
$.map(FrequencyEditor.suffixes, function(v, k) {
|
||||||
$.map(this.suffixes, function(v, k) {
|
|
||||||
// fix lowercase "kHz"
|
// fix lowercase "kHz"
|
||||||
if (k === "K") k = "k";
|
if (k === "K") k = "k";
|
||||||
return '<option value="' + v + '">' + k + 'Hz</option>';
|
return '<option value="' + v + '">' + k + 'Hz</option>';
|
||||||
@ -117,8 +118,8 @@ FrequencyEditor.prototype.setupEvents = function() {
|
|||||||
if (e.keyCode == 13) return me.submit();
|
if (e.keyCode == 13) return me.submit();
|
||||||
if (e.keyCode == 27) return me.cancel();
|
if (e.keyCode == 27) return me.cancel();
|
||||||
var c = String.fromCharCode(e.which);
|
var c = String.fromCharCode(e.which);
|
||||||
if (c in me.suffixes) {
|
if (c in FrequencyEditor.suffixes) {
|
||||||
me.expInput.val(me.suffixes[c]);
|
me.expInput.val(FrequencyEditor.suffixes[c]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -132,7 +133,7 @@ FrequencyEditor.prototype.getValue = function() {
|
|||||||
FrequencyEditor.prototype.setValue = function(value) {
|
FrequencyEditor.prototype.setValue = function(value) {
|
||||||
var value = parseFloat(value);
|
var value = parseFloat(value);
|
||||||
var exp = 0;
|
var exp = 0;
|
||||||
if (!Number.isNaN(value)) {
|
if (!Number.isNaN(value) && value > 0) {
|
||||||
exp = Math.floor(Math.log10(value) / 3) * 3;
|
exp = Math.floor(Math.log10(value) / 3) * 3;
|
||||||
}
|
}
|
||||||
this.freqInput.val(value / 10 ** exp);
|
this.freqInput.val(value / 10 ** exp);
|
||||||
@ -143,15 +144,26 @@ FrequencyEditor.prototype.focus = function() {
|
|||||||
this.freqInput.focus();
|
this.freqInput.focus();
|
||||||
};
|
};
|
||||||
|
|
||||||
FrequencyEditor.prototype.getHtml = function() {
|
var renderFrequency = function(freq) {
|
||||||
var value = this.getValue();
|
|
||||||
var exp = 0;
|
var exp = 0;
|
||||||
if (!Number.isNaN(value)) {
|
if (!Number.isNaN(freq)) {
|
||||||
exp = Math.floor(Math.log10(value) / 3) * 3;
|
exp = Math.floor(Math.log10(freq) / 3) * 3;
|
||||||
}
|
}
|
||||||
var frequency = value / 10 ** exp;
|
var frequency = freq / 10 ** exp;
|
||||||
var expString = this.expInput.find('option[value=' + exp + ']').html();
|
var suffix = Object.entries(FrequencyEditor.suffixes).find(function(e) {
|
||||||
|
return e[1] == exp;
|
||||||
|
});
|
||||||
|
if (!suffix) {
|
||||||
|
return freq + ' Hz';
|
||||||
|
}
|
||||||
|
// fix lowercase 'kHz'
|
||||||
|
suffix = suffix[0] == 'K' ? 'k' : suffix[0];
|
||||||
|
var expString = suffix[0] + 'Hz';
|
||||||
return frequency + ' ' + expString;
|
return frequency + ' ' + expString;
|
||||||
|
}
|
||||||
|
|
||||||
|
FrequencyEditor.prototype.getHtml = function() {
|
||||||
|
return renderFrequency(this.getValue());
|
||||||
};
|
};
|
||||||
|
|
||||||
function ModulationEditor(table) {
|
function ModulationEditor(table) {
|
||||||
@ -313,5 +325,36 @@ $.fn.bookmarktable = function() {
|
|||||||
$table.append(row);
|
$table.append(row);
|
||||||
row[0].scrollIntoView();
|
row[0].scrollIntoView();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var $importModal = $('#importModal').modal({show: false});
|
||||||
|
|
||||||
|
$(this).find('.bookmark-import').on('click', function() {
|
||||||
|
var storage = new BookmarkLocalStorage();
|
||||||
|
var bookmarks = storage.getBookmarks();
|
||||||
|
if (bookmarks.length) {
|
||||||
|
var modes = $table.data('modes');
|
||||||
|
var $list = $('<table class="table table-sm">');
|
||||||
|
$list.append(bookmarks.map(function(b) {
|
||||||
|
var modulation = b.modulation;
|
||||||
|
if (modulation in modes) {
|
||||||
|
modulation = modes[modulation];
|
||||||
|
}
|
||||||
|
var row = $(
|
||||||
|
'<tr>' +
|
||||||
|
'<td><input class="form-check-input" type="checkbox" value="1"></td>' +
|
||||||
|
'<td>' + b.name + '</td>' +
|
||||||
|
'<td class="frequency">' + renderFrequency(b.frequency) + '</td>' +
|
||||||
|
'<td>' + modulation + '</td>' +
|
||||||
|
'</tr>'
|
||||||
|
);
|
||||||
|
row.data('bookmark', b);
|
||||||
|
return row;
|
||||||
|
}));
|
||||||
|
$importModal.find('.bookmark-list').html($list);
|
||||||
|
} else {
|
||||||
|
$importModal.find('.bookmark-list').html('No personal bookmarks found in this browser');
|
||||||
|
}
|
||||||
|
$importModal.modal('show');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -20,6 +20,7 @@ ${header}
|
|||||||
<div class="row mt-3 bookmarks">
|
<div class="row mt-3 bookmarks">
|
||||||
${bookmarks}
|
${bookmarks}
|
||||||
<div class="buttons container">
|
<div class="buttons container">
|
||||||
|
<button type="button" class="btn btn-info bookmark-import">Import personal bookmarks...</button>
|
||||||
<button type="button" class="btn btn-primary bookmark-add">Add a new bookmark</button>
|
<button type="button" class="btn btn-primary bookmark-add">Add a new bookmark</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -43,4 +44,24 @@ ${header}
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="modal" id="importModal" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5>Please select</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<p>Please select the bookmarks you would like to import:</p>
|
||||||
|
<div class="bookmark-list"></div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary cancel" data-dismiss="modal">Cancel</button>
|
||||||
|
<button type="button" class="btn btn-primary confirm">Import</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
@ -125,6 +125,7 @@ class CompiledAssetsController(GzipMixin, ModificationAwareController):
|
|||||||
"lib/Header.js",
|
"lib/Header.js",
|
||||||
"lib/Demodulator.js",
|
"lib/Demodulator.js",
|
||||||
"lib/DemodulatorPanel.js",
|
"lib/DemodulatorPanel.js",
|
||||||
|
"lib/BookmarkLocalStorage.js",
|
||||||
"lib/BookmarkBar.js",
|
"lib/BookmarkBar.js",
|
||||||
"lib/BookmarkDialog.js",
|
"lib/BookmarkDialog.js",
|
||||||
"lib/AudioEngine.js",
|
"lib/AudioEngine.js",
|
||||||
@ -148,6 +149,7 @@ class CompiledAssetsController(GzipMixin, ModificationAwareController):
|
|||||||
"lib/Header.js",
|
"lib/Header.js",
|
||||||
"lib/settings/MapInput.js",
|
"lib/settings/MapInput.js",
|
||||||
"lib/settings/ImageUpload.js",
|
"lib/settings/ImageUpload.js",
|
||||||
|
"lib/BookmarkLocalStorage.js",
|
||||||
"lib/settings/BookmarkTable.js",
|
"lib/settings/BookmarkTable.js",
|
||||||
"lib/settings/WsjtDecodingDepthsInput.js",
|
"lib/settings/WsjtDecodingDepthsInput.js",
|
||||||
"lib/settings/WaterfallDropdown.js",
|
"lib/settings/WaterfallDropdown.js",
|
||||||
|
@ -43,7 +43,9 @@ class BookmarksController(AuthorizationMixin, WebpageController):
|
|||||||
9: "G",
|
9: "G",
|
||||||
12: "T",
|
12: "T",
|
||||||
}
|
}
|
||||||
exp = int(math.log10(freq) / 3) * 3
|
exp = 0
|
||||||
|
if freq > 0:
|
||||||
|
exp = int(math.log10(freq) / 3) * 3
|
||||||
num = freq
|
num = freq
|
||||||
suffix = ""
|
suffix = ""
|
||||||
if exp in suffixes:
|
if exp in suffixes:
|
||||||
|
Loading…
Reference in New Issue
Block a user