It works! "Install" installs the style.

Added an 'error' container for search-related errors.
This commit is contained in:
derv82 2017-11-20 01:11:32 -08:00
parent 16d32c40f5
commit 98c9024eb9
3 changed files with 65 additions and 57 deletions

View File

@ -147,6 +147,7 @@
<a id="load-search-results-link" href="#" <a id="load-search-results-link" href="#"
i18n-text="loadStylesForSite"></a> i18n-text="loadStylesForSite"></a>
</div> </div>
<div id="searchResults-error" class="hidden"></div>
<div id="find-styles"> <div id="find-styles">
<a id="find-styles-link" href="https://userstyles.org/styles/browse/" <a id="find-styles-link" href="https://userstyles.org/styles/browse/"
i18n-text="findStylesForSite"></a> i18n-text="findStylesForSite"></a>

View File

@ -9,10 +9,19 @@
} }
#searchResults.hidden, #searchResults.hidden,
#searchResults-error.hidden,
#load-search-results.hidden { #load-search-results.hidden {
display: none; display: none;
} }
#searchResults-error {
background-color: rgba(255, 0, 0, 0.4);
font-weight: bold;
padding: 5px;
text-align: center;
margin-right: 20px;
}
#searchResults, #searchResults-list { #searchResults, #searchResults-list {
max-width: 200px; max-width: 200px;
overflow: hidden; overflow: hidden;

View File

@ -1,4 +1,4 @@
/* global handleEvent */ /* global handleEvent tryJSONparse */
'use strict'; 'use strict';
/** /**
@ -21,21 +21,19 @@ const UserStylesAPI = (() => {
'Content-type': 'application/json', 'Content-type': 'application/json',
'Accept': '*/*' 'Accept': '*/*'
}; };
let url = 'https://userstyles.org' + path;
const url = new URL('https://userstyles.org');
url.pathname = path;
if (queryParams) { if (queryParams) {
url += '?' + queryParams; url.search = '?' + queryParams;
} }
const xhr = new XMLHttpRequest(); const xhr = new XMLHttpRequest();
xhr.timeout = TIMEOUT; xhr.timeout = TIMEOUT;
xhr.onload = () => { xhr.onload = () => {
if (xhr.status === 200 || url.protocol === 'file:') { if (xhr.status === 200) {
try { resolve(tryJSONparse(xhr.responseText));
resolve(JSON.parse(xhr.responseText));
} catch (err) {
reject('Failed to parse JSON from ' + url + '\nJSON Text: ' + xhr.responseText);
}
} else { } else {
reject('Error code ' + xhr.status); reject(xhr.status);
} }
}; };
xhr.onerror = reject; xhr.onerror = reject;
@ -56,7 +54,37 @@ const UserStylesAPI = (() => {
const SearchResults = (() => { const SearchResults = (() => {
let currentPage = 1; let currentPage = 1;
return {load, next, prev} return {load, next, prev};
/** Increments currentPage and loads results. */
function next(event) {
currentPage += 1;
return load(event);
}
/** Decrements currentPage and loads results. */
function prev(event) {
currentPage = Math.max(1, currentPage - 1);
return load(event);
}
/**
* Display error message to user.
* @param {string} message Message to display to user.
*/
function error(reason) {
let message;
if (reason === 404) {
// TODO: i18n message
message = 'No results found';
} else {
console.log('Error loading search results: ' + reason);
message = 'Error loading search results: ' + reason;
}
$('#searchResults').classList.add('hidden');
$('#searchResults-error').innerHTML = message;
$('#searchResults-error').classList.remove('hidden');
}
/** /**
* Loads search result for the (page number is currentPage). * Loads search result for the (page number is currentPage).
@ -70,6 +98,7 @@ const SearchResults = (() => {
getActiveTab().then(tab => { getActiveTab().then(tab => {
$('#load-search-results').classList.add('hidden'); $('#load-search-results').classList.add('hidden');
$('#searchResults').classList.remove('hidden'); $('#searchResults').classList.remove('hidden');
$('#searchResults-error').classList.add('hidden');
const hostname = new URL(tab.url).hostname.replace(/^(?:.*\.)?([^.]*\.(co\.)?[^.]*)$/i, '$1'); const hostname = new URL(tab.url).hostname.replace(/^(?:.*\.)?([^.]*\.(co\.)?[^.]*)$/i, '$1');
$('#searchResults-terms').textContent = hostname; $('#searchResults-terms').textContent = hostname;
@ -79,6 +108,7 @@ const SearchResults = (() => {
'page=' + currentPage, 'page=' + currentPage,
'per_page=3' 'per_page=3'
].join('&'); ].join('&');
UserStylesAPI.fetch('/api/v1/styles/search', queryParams) UserStylesAPI.fetch('/api/v1/styles/search', queryParams)
.then(searchResults => { .then(searchResults => {
/* /*
@ -91,33 +121,17 @@ const SearchResults = (() => {
} }
*/ */
if (searchResults.data.length === 0) { if (searchResults.data.length === 0) {
throw 'No results found'; throw 404;
} }
currentPage = searchResults.current_page; currentPage = searchResults.current_page;
updateSearchResultsNav(searchResults.current_page, searchResults.total_pages); updateSearchResultsNav(searchResults.current_page, searchResults.total_pages);
searchResults.data.forEach(createSearchResult); searchResults.data.forEach(createSearchResult);
}) })
.catch(reason => { .catch(error);
$('#load-search-results').classList.remove('hidden'); });
$('#searchResults').classList.add('hidden');
alert('Error while loading search results: ' + reason);
});
});
return true; return true;
} }
/** Increments currentPage and loads results. */
function next(event) {
currentPage += 1;
return load(event);
}
/** Decrements currentPage and loads results. */
function prev(event) {
currentPage = Math.max(1, currentPage - 1);
return load(event);
}
/** Updates prev/next buttons and currentPage/totalPage labels. */ /** Updates prev/next buttons and currentPage/totalPage labels. */
function updateSearchResultsNav(currentPage, totalPages) { function updateSearchResultsNav(currentPage, totalPages) {
// Update 'next' button // Update 'next' button
@ -206,38 +220,22 @@ const SearchResults = (() => {
// TODO: Rating // TODO: Rating
const installButton = $('.searchResult-install', entry); const installButton = $('.searchResult-install', entry);
Object.assign(installButton, { installButton.onclick = install;
onclick: install
});
/** Installs the current userstyleSearchResult into stylus. */ /** Installs the current userstyleSearchResult into stylus. */
function install() { function install() {
UserStylesAPI.fetch('/api/v1/styles/' + userstyleSearchResult.id) // TODO: Detect if style has customizations, point to style page if so.
.then(styleObject => { const styleId = userstyleSearchResult.id;
console.log('TODO: Install style ID', userstyleSearchResult.id); const url = 'https://userstyles.org/styles/chrome/' + styleId + '.json';
console.log('Full styleObject:', styleObject); download(url)
/* .then(responseText => {
* FIXME saveStyleSafe(tryJSONparse(responseText));
* Sample full styleObject: https://userstyles.org/api/v1/styles/70271 installButton.disabled = 'disabled';
* We need to convert this sytleObject into the format expected by saveStyleSafe installButton.textContent = 'Installed';
* I.e. styleObject.id is the ID of the userstyles.org style (e.g. 70271 above)
*/
// messaging.js#saveStyleSafe({...}) expects an "id" referring to the Stylus ID (1-n).
delete styleObject.id;
Object.assign(styleObject, {
// TODO: Massage styleObject into the format expected by saveStyleSafe
enabled: true,
reason: 'update',
notify: true
});
saveStyleSafe(styleObject);
alert('TODO: Install style ID #' + userstyleSearchResult.id + ' name "' + searchResultName + '"');
}) })
.catch(reason => { .catch(reason => {
console.log('Error during installation:', reason); console.log('Error while installing from ' + url + ': ' + reason);
alert('Error installing style: ' + reason); alert('Error while installing from ' + url + ': ' + reason);
}); });
return true; return true;
} }