diff --git a/package-lock.json b/package-lock.json index 386fbca..3780e8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3755,6 +3755,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, + "lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", diff --git a/package.json b/package.json index 264b8ef..605f539 100644 --- a/package.json +++ b/package.json @@ -70,6 +70,7 @@ "dayjs": "^1.10.6", "electron-squirrel-startup": "^1.0.0", "fast-xml-parser": "^3.19.0", + "lodash-es": "^4.17.21", "node-ssdp": "^4.0.1", "soap": "^0.40.0", "vue": "^3.2.2" diff --git a/src/index.html b/src/index.html index 88f2a84..2351bf3 100644 --- a/src/index.html +++ b/src/index.html @@ -56,7 +56,7 @@

{{ currentContainer['dc:title'] }} {{ currentMediaServer.name }}

- +
  1. diff --git a/src/index.js b/src/index.js index 5601f45..0b75ad2 100644 --- a/src/index.js +++ b/src/index.js @@ -3,6 +3,7 @@ // Alternatively, omit the .prod from the path for Vue debugging purposes. import {createApp} from '../node_modules/vue/dist/vue.esm-browser.prod.js'; +import debounce from '../node_modules/lodash-es/debounce.js' let api = window.muspnpapi; dayjs.extend(dayjs_plugin_duration); @@ -69,7 +70,7 @@ window.app = createApp({ transportInfo: null, currentVolume: null, searchCapabilities: null, - search: null, + searchTerm: null, searchCache: createObservableCache() } }, @@ -77,7 +78,7 @@ window.app = createApp({ currentMediaServer: function (device) { this.showSpinner = true; this.libraryObjectsCache = createObservableCache(); - this.search = null; + this.searchTerm = null; this.searchCache = createObservableCache() this.selectedItem = []; this.searchCapabilities = null; @@ -115,18 +116,8 @@ window.app = createApp({ } } }, - search: function (search) { - if (! search) { - return; - } - const searchStr = this.searchCapabilities.map(sc => `${sc} contains "${search}"`).join(' or ') - return api - .search({id: 0, start: 0, count: 0, search: searchStr}) - .then(result => { - if (result.UpdateID == null || this.searchCache?.[search]?.UpdateID !== result.UpdateID) { - this.searchCache[search] = result; - } - }) + searchTerm: function (search) { + this.search(search); }, }, created: function () { @@ -135,7 +126,9 @@ window.app = createApp({ get(target, propKey) { // Proxy API for automatic error cleanup // NB: api is a frozen object so we're a bit restricted here... - app.error = null; + if (! ['getPositionInfo', 'getTransportInfo'].includes(propKey)) { + app.error = null; + } return target[propKey]; } }; @@ -152,6 +145,8 @@ window.app = createApp({ api .ssdpSearch() .catch(err => this.error = err); + + this.search = debounce(this._search, 500); }, computed: { currentContainer: function () { @@ -206,8 +201,8 @@ window.app = createApp({ return this._currentPosition_currentPosition.format('HH:mm:ss') }, libraryObjects: function () { - if (this.search) { - return this.searchCache[this.search]?.Result; + if (this.searchTerm) { + return this.searchCache[this.searchTerm]?.Result; } if (this.currentContainer == null) { return this.libraryObjectsCache?.[0]?.Result; @@ -235,7 +230,7 @@ window.app = createApp({ }, selectItem: function (item) { if (item['upnp:class'].startsWith('object.container')) { - this.search = null; + this.searchTerm = null; this.selectedItem.push(item); this.browse({id: item['@_id'], start: 0, count: 0}); return; @@ -307,6 +302,21 @@ window.app = createApp({ .then(() => this.startRefresh(5000)) .catch(err => this.error = err); }, + _search: function (search) { + if (! search) { + return; + } + this.showSpinner = true; + const searchStr = this.searchCapabilities.map(sc => `${sc} contains "${search}"`).join(' or ') + return api + .search({id: 0, start: 0, count: 0, search: searchStr}) + .then(result => { + if (result.UpdateID == null || this.searchCache?.[search]?.UpdateID !== result.UpdateID) { + this.searchCache[search] = result; + } + this.showSpinner = false; + }) + }, seek: function (e) { if (this._currentPosition_duration == null || this._currentPosition_currentPosition == null) { return;