search working, but no rendering of channels

This commit is contained in:
Jeremy Kauffman 2017-10-06 17:46:41 -04:00
parent 80f1cac4e5
commit 91d4dd610e
11 changed files with 56 additions and 180 deletions

View file

@ -16,6 +16,8 @@ Web UI version numbers should always match the corresponding version of LBRY App
* There is no longer a minimum channel length (#645) * There is no longer a minimum channel length (#645)
* Changed the File page to make it clearer how to to open the folder for a file * Changed the File page to make it clearer how to to open the folder for a file
* The upgrade message is now friendlier and includes a link to the release notes. * The upgrade message is now friendlier and includes a link to the release notes.
* Local settings refactored and no longer intermixed with LBRY API library.
*
### Fixed ### Fixed
* Improve layout (and implementation) of the icon panel in file tiles and cards * Improve layout (and implementation) of the icon panel in file tiles and cards

View file

@ -1,6 +1,5 @@
import * as types from "constants/action_types"; import * as types from "constants/action_types";
import lbryuri from "lbryuri"; import lbryuri from "lbryuri";
import lighthouse from "lighthouse";
import { doResolveUri } from "actions/content"; import { doResolveUri } from "actions/content";
import { doNavigate } from "actions/navigation"; import { doNavigate } from "actions/navigation";
import { selectCurrentPage } from "selectors/navigation"; import { selectCurrentPage } from "selectors/navigation";
@ -25,28 +24,41 @@ export function doSearch(query) {
if (page != "search") { if (page != "search") {
dispatch(doNavigate("search", { query: query })); dispatch(doNavigate("search", { query: query }));
} else { } else {
lighthouse.search(query).then(results => { fetch("https://lighthouse.lbry.io/search?s=" + query)
const actions = []; .then(response => {
return response.status === 200
? Promise.resolve(response.json())
: Promise.reject(new Error(response.statusText));
})
.then(data => {
console.log(data);
let uris = [];
let actions = [];
results.forEach(result => { data.forEach(result => {
const uri = lbryuri.build({ const uri = lbryuri.build({
channelName: result.channel_name, name: result.name,
contentName: result.name, claimId: result.claimId,
claimId: result.channel_id || result.claim_id, });
actions.push(doResolveUri(uri));
uris.push(uri);
}); });
actions.push(doResolveUri(uri));
});
actions.push({ actions.push({
type: types.SEARCH_COMPLETED, type: types.SEARCH_COMPLETED,
data: { data: {
query, query,
results, uris,
}, },
});
dispatch(batchActions(...actions));
})
.catch(err => {
console.log(err);
dispatch({
type: types.SEARCH_CANCELLED,
});
}); });
dispatch(batchActions(...actions));
});
} }
}; };
} }

View file

@ -1,22 +1,15 @@
import React from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { doSearch } from "actions/search"; import { doSearch } from "actions/search";
import { import { selectIsSearching, makeSelectSearchUris } from "selectors/search";
selectIsSearching,
selectCurrentSearchResults,
selectSearchQuery,
} from "selectors/search";
import { doNavigate } from "actions/navigation";
import FileListSearch from "./view"; import FileListSearch from "./view";
const select = state => ({ const select = (state, props) => ({
isSearching: selectIsSearching(state), isSearching: selectIsSearching(state),
query: selectSearchQuery(state), uris: makeSelectSearchUris(props.query)(state),
results: selectCurrentSearchResults(state),
}); });
const perform = dispatch => ({ const perform = dispatch => ({
navigate: path => dispatch(doNavigate(path)),
search: search => dispatch(doSearch(search)), search: search => dispatch(doSearch(search)),
}); });

View file

@ -1,52 +1,21 @@
import React from "react"; import React from "react";
import lbry from "lbry";
import lbryio from "lbryio";
import lbryuri from "lbryuri";
import lighthouse from "lighthouse";
import FileTile from "component/fileTile"; import FileTile from "component/fileTile";
import Link from "component/link"; import Link from "component/link";
import { ToolTip } from "component/tooltip.js";
import { BusyMessage } from "component/common.js"; import { BusyMessage } from "component/common.js";
const SearchNoResults = props => { const SearchNoResults = props => {
const { navigate, query } = props; const { query } = props;
return ( return (
<section> <section>
<span className="empty"> <span className="empty">
{(__("No one has checked anything in for %s yet."), query)} {" "} {(__("No one has checked anything in for %s yet."), query)} {" "}
<Link label={__("Be the first")} onClick={() => navigate("/publish")} /> <Link label={__("Be the first")} navigate="/publish" />
</span> </span>
</section> </section>
); );
}; };
const FileListSearchResults = props => {
const { results } = props;
const rows = [],
seenNames = {}; //fix this when the search API returns claim IDs
for (let {
name,
claim,
claim_id,
channel_name,
channel_id,
txid,
nout,
} of results) {
const uri = lbryuri.build({
channelName: channel_name,
contentName: name,
claimId: channel_id || claim_id,
});
rows.push(<FileTile key={uri} uri={uri} />);
}
return <div>{rows}</div>;
};
class FileListSearch extends React.PureComponent { class FileListSearch extends React.PureComponent {
componentWillMount() { componentWillMount() {
this.doSearch(this.props); this.doSearch(this.props);
@ -63,21 +32,21 @@ class FileListSearch extends React.PureComponent {
} }
render() { render() {
const { isSearching, results } = this.props; const { isSearching, uris, query } = this.props;
return ( return (
<div> <div>
{isSearching && {isSearching &&
!results && !uris &&
<BusyMessage message={__("Looking up the Dewey Decimals")} />} <BusyMessage message={__("Looking up the Dewey Decimals")} />}
{isSearching && {isSearching &&
results && uris &&
<BusyMessage message={__("Refreshing the Dewey Decimals")} />} <BusyMessage message={__("Refreshing the Dewey Decimals")} />}
{results && !!results.length {uris && uris.length
? <FileListSearchResults {...this.props} /> ? uris.map(uri => <FileTile key={uri} uri={uri} />)
: !isSearching && <SearchNoResults {...this.props} />} : !isSearching && <SearchNoResults query={query} />}
</div> </div>
); );
} }

View file

@ -2,8 +2,6 @@ import React from "react";
import * as icons from "constants/icons"; import * as icons from "constants/icons";
import lbryuri from "lbryuri.js"; import lbryuri from "lbryuri.js";
import CardMedia from "component/cardMedia"; import CardMedia from "component/cardMedia";
import FileActions from "component/fileActions";
import Link from "component/link";
import { TruncatedText } from "component/common.js"; import { TruncatedText } from "component/common.js";
import FilePrice from "component/filePrice"; import FilePrice from "component/filePrice";
import NsfwOverlay from "component/nsfwOverlay"; import NsfwOverlay from "component/nsfwOverlay";

View file

@ -1,82 +0,0 @@
import lbry from "./lbry.js";
import jsonrpc from "./jsonrpc.js";
const queryTimeout = 3000;
const maxQueryTries = 2;
const defaultServers = [
"http://lighthouse7.lbry.io:50005",
"http://lighthouse8.lbry.io:50005",
"http://lighthouse9.lbry.io:50005",
];
const path = "/";
let server = null;
let connectTryNum = 0;
function getServers() {
return defaultServers;
}
function call(method, params, callback, errorCallback) {
if (connectTryNum >= maxQueryTries) {
errorCallback(
new Error(
__(
`Could not connect to Lighthouse server. Last server attempted: %s`,
server
)
)
);
return;
}
/**
* Set the Lighthouse server if it hasn't been set yet, if the current server is not in current
* set of servers (most likely because of a settings change), or we're re-trying after a failed
* query.
*/
if (!server || !getServers().includes(server) || connectTryNum > 0) {
// If there's a current server, filter it out so we get a new one
const newServerChoices = server
? getServers().filter(s => s != server)
: getServers();
server =
newServerChoices[
Math.round(Math.random() * (newServerChoices.length - 1))
];
}
jsonrpc.call(
server + path,
method,
params,
response => {
connectTryNum = 0;
callback(response);
},
error => {
connectTryNum = 0;
errorCallback(error);
},
() => {
connectTryNum++;
call(method, params, callback, errorCallback);
},
queryTimeout
);
}
const lighthouse = new Proxy(
{},
{
get: function(target, name) {
return function(...params) {
return new Promise((resolve, reject) => {
call(name, params, resolve, reject);
});
};
},
}
);
export default lighthouse;

View file

@ -1,6 +1,5 @@
import React from "react"; import React from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import lbry from "./lbry.js";
import App from "component/app/index.js"; import App from "component/app/index.js";
import SnackBar from "component/snackBar"; import SnackBar from "component/snackBar";
import { Provider } from "react-redux"; import { Provider } from "react-redux";

View file

@ -1,10 +1,6 @@
import React from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { import { selectIsSearching, selectSearchQuery } from "selectors/search";
selectIsSearching,
selectSearchQuery,
selectCurrentSearchResults,
} from "selectors/search";
import { doNavigate } from "actions/navigation"; import { doNavigate } from "actions/navigation";
import SearchPage from "./view"; import SearchPage from "./view";

View file

@ -3,7 +3,6 @@ import lbryuri from "lbryuri";
import FileTile from "component/fileTile"; import FileTile from "component/fileTile";
import FileListSearch from "component/fileListSearch"; import FileListSearch from "component/fileListSearch";
import { ToolTip } from "component/tooltip.js"; import { ToolTip } from "component/tooltip.js";
import { BusyMessage } from "component/common.js";
class SearchPage extends React.PureComponent { class SearchPage extends React.PureComponent {
render() { render() {

View file

@ -1,7 +1,10 @@
import * as types from "constants/action_types"; import * as types from "constants/action_types";
const reducers = {}; const reducers = {};
const defaultState = {}; const defaultState = {
urisByQuery: {},
searching: false,
};
reducers[types.SEARCH_STARTED] = function(state, action) { reducers[types.SEARCH_STARTED] = function(state, action) {
const { query } = action.data; const { query } = action.data;
@ -12,17 +15,11 @@ reducers[types.SEARCH_STARTED] = function(state, action) {
}; };
reducers[types.SEARCH_COMPLETED] = function(state, action) { reducers[types.SEARCH_COMPLETED] = function(state, action) {
const { query, results } = action.data; const { query, uris } = action.data;
const oldResults = Object.assign({}, state.results);
const newByQuery = Object.assign({}, oldResults.byQuery);
newByQuery[query] = results;
const newResults = Object.assign({}, oldResults, {
byQuery: newByQuery,
});
return Object.assign({}, state, { return Object.assign({}, state, {
searching: false, searching: false,
results: newResults, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }),
}); });
}; };

View file

@ -18,21 +18,14 @@ export const selectIsSearching = createSelector(
state => !!state.searching state => !!state.searching
); );
export const selectSearchResults = createSelector( export const selectSearchUrisByQuery = createSelector(
_selectState, _selectState,
state => state.results || {} state => state.urisByQuery
); );
export const selectSearchResultsByQuery = createSelector( export const makeSelectSearchUris = query => {
selectSearchResults, return createSelector(selectSearchUrisByQuery, byQuery => byQuery[query]);
results => results.byQuery || {} };
);
export const selectCurrentSearchResults = createSelector(
selectSearchQuery,
selectSearchResultsByQuery,
(query, byQuery) => byQuery[query]
);
export const selectWunderBarAddress = createSelector( export const selectWunderBarAddress = createSelector(
selectCurrentPage, selectCurrentPage,