function BookmarkBar() { var me = this; me.localBookmarks = new BookmarkLocalStorage(); me.$container = $("#openwebrx-bookmarks-container"); me.bookmarks = {}; me.$container.on('click', '.bookmark', function(e){ var $bookmark = $(e.target).closest('.bookmark'); me.$container.find('.bookmark').removeClass('selected'); var b = $bookmark.data(); if (!b || !b.frequency || (!b.modulation && !b.digital_modulation)) return; demodulator_set_offset_frequency(0, b.frequency - center_freq); if (b.modulation) { demodulator_analog_replace(b.modulation); } else if (b.digital_modulation) { demodulator_digital_replace(b.digital_modulation); } $bookmark.addClass('selected'); }); me.$container.on('click', '.action[data-action=edit]', function(e){ e.stopPropagation(); var $bookmark = $(e.target).closest('.bookmark'); me.showEditDialog($bookmark.data()); }); me.$container.on('click', '.action[data-action=delete]', function(e){ e.stopPropagation(); var $bookmark = $(e.target).closest('.bookmark'); me.localBookmarks.deleteBookmark($bookmark.data()); me.loadLocalBookmarks(); }); var $bookmarkButton = $('#openwebrx-panel-receiver').find('.openwebrx-bookmark-button'); if (typeof(Storage) !== 'undefined') { $bookmarkButton.show(); } else { $bookmarkButton.hide(); } $bookmarkButton.click(function(){ me.showEditDialog(); }); me.$dialog = $("#openwebrx-dialog-bookmark"); me.$dialog.find('.openwebrx-button[data-action=cancel]').click(function(){ me.$dialog.hide(); }); me.$dialog.find('.openwebrx-button[data-action=submit]').click(function(){ me.storeBookmark(); }); me.$dialog.find('form').on('submit', function(e){ e.preventDefault(); me.storeBookmark(); }); } BookmarkBar.prototype.position = function(){ var range = get_visible_freq_range(); $('#openwebrx-bookmarks-container').find('.bookmark').each(function(){ $(this).css('left', scale_px_from_freq($(this).data('frequency'), range)); }); }; BookmarkBar.prototype.loadLocalBookmarks = function(){ var bwh = bandwidth / 2; var start = center_freq - bwh; var end = center_freq + bwh; var bookmarks = this.localBookmarks.getBookmarks().filter(function(b){ return b.frequency >= start && b.frequency <= end; }); this.replace_bookmarks(bookmarks, 'local', true); }; BookmarkBar.prototype.replace_bookmarks = function(bookmarks, source, editable) { editable = !!editable; bookmarks = bookmarks.map(function(b){ b.source = source; b.editable = editable; return b; }); this.bookmarks[source] = bookmarks; this.render(); }; BookmarkBar.prototype.render = function(){ var bookmarks = Object.values(this.bookmarks).reduce(function(l, v){ return l.concat(v); }); bookmarks = bookmarks.sort(function(a, b){ return a.frequency - b.frequency; }); var elements = bookmarks.map(function(b){ var $bookmark = $( '