From 1e89179f095ac3dce28e400afc42527f19ce7a10 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Fri, 21 Oct 2022 02:09:26 -0500 Subject: [PATCH] Page-load with the correct homeserver selected (#98) Page-load with the correct homeserver selected (according to `?homeserver`). Fix https://github.com/matrix-org/matrix-public-archive/issues/92 Also makes sure that the `?homeserver` is always available somewhere in the list; whether that be in the available homeserver list or the added homeserver list depending on it someone cleared it out or never had it because they visited from someone else's link. --- package-lock.json | 197 +++++++++++--------- package.json | 4 +- server/routes/room-directory-routes.js | 4 +- shared/room-directory-vm-render-script.js | 5 +- shared/viewmodels/RoomDirectoryViewModel.js | 48 ++++- shared/views/RoomDirectoryView.js | 60 +++++- test/e2e-tests.js | 9 + 7 files changed, 214 insertions(+), 113 deletions(-) diff --git a/package-lock.json b/package-lock.json index 672eabb..79105a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,9 +21,9 @@ "@opentelemetry/semantic-conventions": "^1.3.1", "dompurify": "^2.3.9", "express": "^4.17.2", - "hydrogen-view-sdk": "npm:@mlm/hydrogen-view-sdk@^0.19.0-scratch", + "hydrogen-view-sdk": "npm:@mlm/hydrogen-view-sdk@^0.20.0-scratch", "json5": "^2.2.1", - "linkedom": "^0.14.1", + "linkedom": "^0.14.17", "matrix-public-archive-shared": "file:./shared/", "nconf": "^0.11.3", "node-fetch": "^2.6.7", @@ -2216,7 +2216,8 @@ }, "node_modules/boolbase": { "version": "1.0.0", - "license": "ISC" + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "node_modules/boxen": { "version": "5.1.2", @@ -2552,13 +2553,14 @@ } }, "node_modules/css-select": { - "version": "4.2.1", - "license": "BSD-2-Clause", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dependencies": { "boolbase": "^1.0.0", - "css-what": "^5.1.0", - "domhandler": "^4.3.0", - "domutils": "^2.8.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", "nth-check": "^2.0.1" }, "funding": { @@ -2566,8 +2568,9 @@ } }, "node_modules/css-what": { - "version": "5.1.0", - "license": "BSD-2-Clause", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", "engines": { "node": ">= 6" }, @@ -2664,32 +2667,35 @@ } }, "node_modules/dom-serializer": { - "version": "1.3.2", - "license": "MIT", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, "funding": { "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, "node_modules/domelementtype": { - "version": "2.2.0", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", "funding": [ { "type": "github", "url": "https://github.com/sponsors/fb55" } - ], - "license": "BSD-2-Clause" + ] }, "node_modules/domhandler": { - "version": "4.3.0", - "license": "BSD-2-Clause", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dependencies": { - "domelementtype": "^2.2.0" + "domelementtype": "^2.3.0" }, "engines": { "node": ">= 4" @@ -2703,12 +2709,13 @@ "license": "(MPL-2.0 OR Apache-2.0)" }, "node_modules/domutils": { - "version": "2.8.0", - "license": "BSD-2-Clause", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" @@ -2763,8 +2770,12 @@ } }, "node_modules/entities": { - "version": "2.2.0", - "license": "BSD-2-Clause", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "engines": { + "node": ">=0.12" + }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -3590,7 +3601,9 @@ "license": "MIT" }, "node_modules/htmlparser2": { - "version": "7.2.0", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", "funding": [ "https://github.com/fb55/htmlparser2?sponsor=1", { @@ -3598,22 +3611,11 @@ "url": "https://github.com/sponsors/fb55" } ], - "license": "MIT", "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "3.0.1", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" } }, "node_modules/http-cache-semantics": { @@ -3637,9 +3639,9 @@ }, "node_modules/hydrogen-view-sdk": { "name": "@mlm/hydrogen-view-sdk", - "version": "0.19.0-scratch", - "resolved": "https://registry.npmjs.org/@mlm/hydrogen-view-sdk/-/hydrogen-view-sdk-0.19.0-scratch.tgz", - "integrity": "sha512-wpb6DAnayXO2Xcb9tHS13JGXgF/kOnqEuSxYdQisxJPDnYDrcqwX7LHTw/yhPvfNKLSv5UpWr7DrMAN1xEhwOg==", + "version": "0.20.0-scratch", + "resolved": "https://registry.npmjs.org/@mlm/hydrogen-view-sdk/-/hydrogen-view-sdk-0.20.0-scratch.tgz", + "integrity": "sha512-5WktCwE3b8BgQ2ICx37c91hWrFJbAg+rUU1DTFeT/sFpRP+USqBHfz5IDrd4EcgZk7/FiMpV1lzpsJ5Wfip1NQ==", "dependencies": { "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz", "another-json": "^0.2.0", @@ -4017,13 +4019,14 @@ "license": "MIT" }, "node_modules/linkedom": { - "version": "0.14.1", - "license": "ISC", + "version": "0.14.17", + "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.14.17.tgz", + "integrity": "sha512-PD6GQKvZ4s6Ai4/WkpyHc8MhiZdCz4hWmMOWJk+MO3/kl1QvPUbo4nQWS9+VHO7lRBk1ucIa9ONS9qzCUcBAmQ==", "dependencies": { - "css-select": "^4.2.1", + "css-select": "^5.1.0", "cssom": "^0.5.0", "html-escaper": "^3.0.3", - "htmlparser2": "^7.2.0", + "htmlparser2": "^8.0.1", "uhyphen": "^0.1.0" } }, @@ -4449,8 +4452,9 @@ } }, "node_modules/nth-check": { - "version": "2.0.1", - "license": "BSD-2-Clause", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dependencies": { "boolbase": "^1.0.0" }, @@ -7181,7 +7185,9 @@ } }, "boolbase": { - "version": "1.0.0" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" }, "boxen": { "version": "5.1.2", @@ -7386,17 +7392,21 @@ "dev": true }, "css-select": { - "version": "4.2.1", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "requires": { "boolbase": "^1.0.0", - "css-what": "^5.1.0", - "domhandler": "^4.3.0", - "domutils": "^2.8.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", "nth-check": "^2.0.1" } }, "css-what": { - "version": "5.1.0" + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==" }, "cssom": { "version": "0.5.0" @@ -7451,31 +7461,39 @@ } }, "dom-serializer": { - "version": "1.3.2", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" } }, "domelementtype": { - "version": "2.2.0" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==" }, "domhandler": { - "version": "4.3.0", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "requires": { - "domelementtype": "^2.2.0" + "domelementtype": "^2.3.0" } }, "dompurify": { "version": "2.3.9" }, "domutils": { - "version": "2.8.0", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz", + "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==", "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.1" } }, "dot-prop": { @@ -7514,7 +7532,9 @@ } }, "entities": { - "version": "2.2.0" + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==" }, "error": { "version": "7.0.2", @@ -8043,17 +8063,14 @@ "version": "3.0.3" }, "htmlparser2": { - "version": "7.2.0", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz", + "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==", "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.2", - "domutils": "^2.8.0", - "entities": "^3.0.1" - }, - "dependencies": { - "entities": { - "version": "3.0.1" - } + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "entities": "^4.3.0" } }, "http-cache-semantics": { @@ -8071,9 +8088,9 @@ } }, "hydrogen-view-sdk": { - "version": "npm:@mlm/hydrogen-view-sdk@0.19.0-scratch", - "resolved": "https://registry.npmjs.org/@mlm/hydrogen-view-sdk/-/hydrogen-view-sdk-0.19.0-scratch.tgz", - "integrity": "sha512-wpb6DAnayXO2Xcb9tHS13JGXgF/kOnqEuSxYdQisxJPDnYDrcqwX7LHTw/yhPvfNKLSv5UpWr7DrMAN1xEhwOg==", + "version": "npm:@mlm/hydrogen-view-sdk@0.20.0-scratch", + "resolved": "https://registry.npmjs.org/@mlm/hydrogen-view-sdk/-/hydrogen-view-sdk-0.20.0-scratch.tgz", + "integrity": "sha512-5WktCwE3b8BgQ2ICx37c91hWrFJbAg+rUU1DTFeT/sFpRP+USqBHfz5IDrd4EcgZk7/FiMpV1lzpsJ5Wfip1NQ==", "requires": { "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz", "another-json": "^0.2.0", @@ -8302,12 +8319,14 @@ } }, "linkedom": { - "version": "0.14.1", + "version": "0.14.17", + "resolved": "https://registry.npmjs.org/linkedom/-/linkedom-0.14.17.tgz", + "integrity": "sha512-PD6GQKvZ4s6Ai4/WkpyHc8MhiZdCz4hWmMOWJk+MO3/kl1QvPUbo4nQWS9+VHO7lRBk1ucIa9ONS9qzCUcBAmQ==", "requires": { - "css-select": "^4.2.1", + "css-select": "^5.1.0", "cssom": "^0.5.0", "html-escaper": "^3.0.3", - "htmlparser2": "^7.2.0", + "htmlparser2": "^8.0.1", "uhyphen": "^0.1.0" } }, @@ -8557,7 +8576,9 @@ "dev": true }, "nth-check": { - "version": "2.0.1", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "requires": { "boolbase": "^1.0.0" } diff --git a/package.json b/package.json index 466cd19..26701a6 100644 --- a/package.json +++ b/package.json @@ -47,9 +47,9 @@ "@opentelemetry/semantic-conventions": "^1.3.1", "dompurify": "^2.3.9", "express": "^4.17.2", - "hydrogen-view-sdk": "npm:@mlm/hydrogen-view-sdk@^0.19.0-scratch", + "hydrogen-view-sdk": "npm:@mlm/hydrogen-view-sdk@^0.20.0-scratch", "json5": "^2.2.1", - "linkedom": "^0.14.1", + "linkedom": "^0.14.17", "matrix-public-archive-shared": "file:./shared/", "nconf": "^0.11.3", "node-fetch": "^2.6.7", diff --git a/server/routes/room-directory-routes.js b/server/routes/room-directory-routes.js index eb86701..cc81a08 100644 --- a/server/routes/room-directory-routes.js +++ b/server/routes/room-directory-routes.js @@ -73,8 +73,8 @@ router.get( : null, nextPaginationToken, prevPaginationToken, - searchParameters: { - homeserver, + pageSearchParameters: { + homeserver: homeserver || matrixServerName, searchTerm, paginationToken, limit, diff --git a/shared/room-directory-vm-render-script.js b/shared/room-directory-vm-render-script.js index b9df7a4..1e65c6b 100644 --- a/shared/room-directory-vm-render-script.js +++ b/shared/room-directory-vm-render-script.js @@ -20,7 +20,7 @@ assert(rooms); const roomFetchError = window.matrixPublicArchiveContext.roomFetchError; const nextPaginationToken = window.matrixPublicArchiveContext.nextPaginationToken; const prevPaginationToken = window.matrixPublicArchiveContext.prevPaginationToken; -const searchParameters = window.matrixPublicArchiveContext.searchParameters; +const pageSearchParameters = window.matrixPublicArchiveContext.pageSearchParameters; const config = window.matrixPublicArchiveContext.config; assert(config); assert(config.matrixServerUrl); @@ -80,11 +80,10 @@ async function mountHydrogen() { matrixPublicArchiveURLCreator, rooms, roomFetchError, - searchParameters, + pageSearchParameters, nextPaginationToken, prevPaginationToken, }); - roomDirectoryViewModel.loadAddedHomserversListFromPersistence(); const view = new RoomDirectoryView(roomDirectoryViewModel); diff --git a/shared/viewmodels/RoomDirectoryViewModel.js b/shared/viewmodels/RoomDirectoryViewModel.js index 4c848a4..491e393 100644 --- a/shared/viewmodels/RoomDirectoryViewModel.js +++ b/shared/viewmodels/RoomDirectoryViewModel.js @@ -20,7 +20,7 @@ class RoomDirectoryViewModel extends ViewModel { matrixPublicArchiveURLCreator, rooms, roomFetchError, - searchParameters, + pageSearchParameters, nextPaginationToken, prevPaginationToken, } = options; @@ -49,13 +49,19 @@ class RoomDirectoryViewModel extends ViewModel { }) ); - this._searchParameters = searchParameters; - this._searchTerm = searchParameters.searchTerm; - this._addedHomeserversList = []; + this._pageSearchParameters = pageSearchParameters; + // Default to what the page started with + this._searchTerm = pageSearchParameters.searchTerm; this._nextPaginationToken = nextPaginationToken; this._prevPaginationToken = prevPaginationToken; - this._homeserverSelection = this.availableHomeserverList[0]; + // The default selected homeserver should be the one according to the page or the first one in the list + this._homeserverSelection = pageSearchParameters.homeserver || this._availableHomeserverList[0]; + // The homeservers that the user added themselves (pulled from LocalStorage) + this._addedHomeserversList = []; + this.loadAddedHomserversListFromPersistence(); + // The default list of homeservers to select from + this._calculateAvailableHomeserverList(); this._homeserverSelectionModalContentViewModel = new HomeserverSelectionModalContentViewModel({ onNewHomeserverAdded: this.onNewHomeserverAdded.bind(this), @@ -105,8 +111,8 @@ class RoomDirectoryViewModel extends ViewModel { return this._matrixPublicArchiveURLCreator.roomDirectoryUrl(); } - get searchParameters() { - return this._searchParameters; + get pageSearchParameters() { + return this._pageSearchParameters; } get searchTerm() { @@ -181,6 +187,12 @@ class RoomDirectoryViewModel extends ViewModel { ADDED_HOMESERVERS_LIST_LOCAL_STORAGE_KEY, JSON.stringify(this._addedHomeserversList) ); + + // If the added homeserver list changes, make sure the default page selected + // homeserver is still somewhere in the list. If it's no longer in the added + // homeserver list, we will put it in the default available list. + this._calculateAvailableHomeserverList(); + this.emitChange('addedHomeserversList'); } @@ -220,10 +232,23 @@ class RoomDirectoryViewModel extends ViewModel { return null; } - get availableHomeserverList() { + // The default list of available homeservers to select from. Deduplicates the the + // homeserver we're pulling from and the `DEFAULT_SERVER_LIST`. Also makes sure that + // the page selected homeserver is either in our default available list or in the + // added servers list. + _calculateAvailableHomeserverList() { // Append the default homeserver to the front const rawList = [this._homeserverName, ...DEFAULT_SERVER_LIST]; + // Make sure the page selected homeserver is in the list somewhere + if ( + this.homeserverSelection && + !rawList.includes(this.homeserverSelection) && + !this._addedHomeserversList.includes(this.homeserverSelection) + ) { + rawList.unshift(this.homeserverSelection); + } + // Then deduplicate the list const deduplicatedHomeserverMap = {}; rawList.forEach((homeserverName) => { @@ -231,7 +256,12 @@ class RoomDirectoryViewModel extends ViewModel { }); const deduplicatedHomeserverList = Object.keys(deduplicatedHomeserverMap); - return deduplicatedHomeserverList; + this._availableHomeserverList = deduplicatedHomeserverList; + this.emit('availableHomeserverList'); + } + + get availableHomeserverList() { + return this._availableHomeserverList; } get rooms() { diff --git a/shared/views/RoomDirectoryView.js b/shared/views/RoomDirectoryView.js index ea81607..bf4d627 100644 --- a/shared/views/RoomDirectoryView.js +++ b/shared/views/RoomDirectoryView.js @@ -28,14 +28,11 @@ class RoomDirectoryView extends TemplateView { } ); - const availableHomeserverOptionElements = vm.availableHomeserverList.map((homeserverName) => { - return t.option({ value: homeserverName }, homeserverName); - }); - const homeserverSelectElement = t.select( { className: 'RoomDirectoryView_homeserverSelector', name: 'homeserver', + 'data-testid': 'homeserver-select', onInput: (event) => { const optionValue = event.target.value; if (optionValue.startsWith('action:')) { @@ -51,13 +48,37 @@ class RoomDirectoryView extends TemplateView { }, }, [ - ...availableHomeserverOptionElements, + t.map( + (vm) => vm.availableHomeserverList, + (_, t, vm) => { + const availableHomeserverOptionElements = vm.availableHomeserverList.map( + (homeserverName) => { + return t.option( + { value: homeserverName, selected: vm.homeserverSelection === homeserverName }, + homeserverName + ); + } + ); + let availableHomeserversOptGroup = text(''); + if (availableHomeserverOptionElements.length > 0) { + availableHomeserversOptGroup = t.optgroup( + { label: 'Defaults' }, + availableHomeserverOptionElements + ); + } + + return availableHomeserversOptGroup; + } + ), t.map( (vm) => vm.addedHomeserversList, (_, t, vm) => { const addedHomeserverOptionElements = vm.addedHomeserversList.map((homeserverName) => { - return t.option({ value: homeserverName }, homeserverName); + return t.option( + { value: homeserverName, selected: vm.homeserverSelection === homeserverName }, + homeserverName + ); }); let addedHomeserversOptGroup = text(''); @@ -153,12 +174,31 @@ class RoomDirectoryView extends TemplateView { const pickedActionOption = homeserverSelection.startsWith('action:'); const isInitialization = oldHomeserverSelection === undefined; if (!pickedActionOption && !isInitialization) { - // Submit the page with the new homeserver selection to get results + // Clear the hash out before we submit the form so it doesn't come back from + // the dead after the page loads. Normally, the hash would go away in the + // modal close callback but this races with it and sometimes we beat it. + const path = vm.navigation.pathFrom([]); + vm.navigation.applyPath(path); + // Submit the page with the new homeserver selection to get results. headerForm.submit(); } } ); + // Also update the selection whenever the lists change around + t.mapSideEffect( + (vm) => vm.availableHomeserverList, + () => { + homeserverSelectElement.value = vm.homeserverSelection; + } + ); + t.mapSideEffect( + (vm) => vm.addedHomeserversList, + () => { + homeserverSelectElement.value = vm.homeserverSelection; + } + ); + return t.div( { className: { @@ -168,13 +208,14 @@ class RoomDirectoryView extends TemplateView { [ t.header({ className: 'RoomDirectoryView_header' }, [headerForm]), t.main({ className: 'RoomDirectoryView_mainContent' }, [ + // Display a nice error section when we failed to fetch rooms from the room directory t.if( (vm) => vm.roomFetchError, (t, vm) => { return t.section({ className: 'RoomDirectoryView_roomListError' }, [ t.h3('❗ Unable to fetch rooms from room directory'), t.p({}, [ - `This may be a temporary problem with the homeserver where the room directory lives (${vm.searchParameters.homeserver}) or the homeserver that the archive is pulling from (${vm.homeserverName}). You can try adjusting your search term or select a different homeserver to look at. If this problem persists, please open a `, + `This may be a temporary problem with the homeserver where the room directory lives (${vm.pageSearchParameters.homeserver}) or the homeserver that the archive is pulling from (${vm.homeserverName}). You can try adjusting your search term or select a different homeserver to look at. If this problem persists, please open a `, t.a( { href: 'https://github.com/matrix-org/matrix-public-archive/issues/new' }, 'bug report' @@ -198,7 +239,7 @@ class RoomDirectoryView extends TemplateView { t.p({}, `The error occured with these search paramers:`), t.pre( { className: 'RoomDirectoryView_codeBlock' }, - t.code({}, JSON.stringify(vm.searchParameters, null, 2)) + t.code({}, JSON.stringify(vm.pageSearchParameters, null, 2)) ), t.details({}, [ t.summary({}, 'Why are we showing so many details?'), @@ -239,6 +280,7 @@ class RoomDirectoryView extends TemplateView { ]); } ), + // Otherwise, display the rooms that we fetched t.view(roomList), t.div({ className: 'RoomDirectoryView_paginationButtonCombo' }, [ t.a( diff --git a/test/e2e-tests.js b/test/e2e-tests.js index dace4b4..86fbf72 100644 --- a/test/e2e-tests.js +++ b/test/e2e-tests.js @@ -700,6 +700,15 @@ describe('matrix-public-archive', () => { const roomDirectoryWithSearchPageHtml = await fetchEndpointAsText(archiveUrl); const domWithSearch = parseHTML(roomDirectoryWithSearchPageHtml); + // Make sure the `?homserver` is selected in the homeserver selector `