Working on search

This commit is contained in:
6ea86b96 2017-04-24 21:17:36 +07:00 committed by Jeremy Kauffman
parent bb9a71805b
commit 768326fb4a
10 changed files with 158 additions and 34 deletions

View file

@ -1,9 +1,12 @@
import * as types from 'constants/action_types' import * as types from 'constants/action_types'
import lbry from 'lbry' import lbry from 'lbry'
import lbryio from 'lbryio'; import lbryio from 'lbryio'
import { import {
selectCurrentUri, selectCurrentUri,
} from 'selectors/app' } from 'selectors/app'
import {
selectSearchTerm,
} from 'selectors/content'
import { import {
selectCurrentResolvedUriClaimOutpoint, selectCurrentResolvedUriClaimOutpoint,
} from 'selectors/content' } from 'selectors/content'

28
ui/js/actions/search.js Normal file
View file

@ -0,0 +1,28 @@
import * as types from 'constants/action_types'
import lbry from 'lbry'
import lbryio from 'lbryio'
import lighthouse from 'lighthouse'
import {
selectSearchQuery,
} from 'selectors/search'
export function doSearchContent(query) {
return function(dispatch, getState) {
const state = getState()
dispatch({
type: types.SEARCH_STARTED,
data: { query }
})
lighthouse.search(query).then(results => {
dispatch({
type: types.SEARCH_COMPLETED,
data: {
query,
results,
}
})
})
}
}

View file

@ -9,6 +9,9 @@ import {
import { import {
doNavigate, doNavigate,
} from 'actions/app' } from 'actions/app'
import {
doSearchContent,
} from 'actions/search'
import Header from './view' import Header from './view'
const select = (state) => ({ const select = (state) => ({
@ -18,6 +21,7 @@ const select = (state) => ({
const perform = (dispatch) => ({ const perform = (dispatch) => ({
navigate: (path) => dispatch(doNavigate(path)), navigate: (path) => dispatch(doNavigate(path)),
search: (query) => dispatch(doSearchContent(query)),
}) })
export default connect(select, perform)(Header) export default connect(select, perform)(Header)

View file

@ -47,3 +47,7 @@ export const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'
export const FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED' export const FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'
export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED' export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'
export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED' export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED'
// Search
export const SEARCH_STARTED = 'SEARCH_STARTED'
export const SEARCH_COMPLETED = 'SEARCH_COMPLETED'

View file

@ -5,10 +5,21 @@ import {
import { import {
selectFeaturedContentByCategory selectFeaturedContentByCategory
} from 'selectors/content' } from 'selectors/content'
import {
doSearchContent,
} from 'actions/search'
import {
selectIsSearching,
selectSearchQuery,
selectCurrentSearchResults,
} from 'selectors/search'
import DiscoverPage from './view' import DiscoverPage from './view'
const select = (state) => ({ const select = (state) => ({
featuredContentByCategory: selectFeaturedContentByCategory(state), featuredContentByCategory: selectFeaturedContentByCategory(state),
isSearching: selectIsSearching(state),
query: selectSearchQuery(state),
results: selectCurrentSearchResults(state),
}) })
const perform = (dispatch) => ({ const perform = (dispatch) => ({

View file

@ -60,6 +60,6 @@ let DiscoverPage = React.createClass({
</div> </div>
}</main>; }</main>;
} }
}); })
export default DiscoverPage; export default DiscoverPage;

View file

@ -2,7 +2,7 @@ import React from 'react';
import lbry from 'lbry.js'; import lbry from 'lbry.js';
import lighthouse from 'lighthouse.js'; import lighthouse from 'lighthouse.js';
import lbryuri from 'lbryuri.js'; import lbryuri from 'lbryuri.js';
import {Video} from 'page/watch.js' import Video from 'page/video'
import { import {
TruncatedText, TruncatedText,
Thumbnail, Thumbnail,
@ -13,22 +13,30 @@ import {FileActions} from 'component/file-actions.js';
import Link from 'component/link'; import Link from 'component/link';
import UriIndicator from 'component/channel-indicator.js'; import UriIndicator from 'component/channel-indicator.js';
var FormatItem = React.createClass({ const FormatItem = (props) => {
propTypes: { const {
metadata: React.PropTypes.object, contentType,
contentType: React.PropTypes.string, metadata,
uri: React.PropTypes.string, cost,
outpoint: React.PropTypes.string, uri,
}, outpoint,
render: function() { costIncludesData,
const {thumbnail, author, title, description, language, license} = this.props.metadata; } = props
const mediaType = lbry.getMediaType(this.props.contentType); const {
thumbnail,
author,
title,
description,
language,
license
} = metadata;
const mediaType = lbry.getMediaType(contentType);
return ( return (
<table className="table-standard"> <table className="table-standard">
<tbody> <tbody>
<tr> <tr>
<td>Content-Type</td><td>{this.props.contentType}</td> <td>Content-Type</td><td>{contentType}</td>
</tr> </tr>
<tr> <tr>
<td>Author</td><td>{author}</td> <td>Author</td><td>{author}</td>
@ -41,9 +49,8 @@ var FormatItem = React.createClass({
</tr> </tr>
</tbody> </tbody>
</table> </table>
); )
} }
});
let ChannelPage = React.createClass({ let ChannelPage = React.createClass({
render: function() { render: function() {

36
ui/js/reducers/search.js Normal file
View file

@ -0,0 +1,36 @@
import * as types from 'constants/action_types'
const reducers = {}
const defaultState = {
}
reducers[types.SEARCH_STARTED] = function(state, action) {
const {
query,
} = action.data
return Object.assign({}, state, {
searching: true,
query: query,
})
}
reducers[types.SEARCH_COMPLETED] = function(state, action) {
const {
query,
} = action.data
const newResults = Object.assign({}, state.results)
const newByQuery = Object.assign({}, newResults.byQuery)
newByQuery[query] = action.data.results
return Object.assign({}, state, {
searching: false,
results: newResults,
})
}
export default function reducer(state = defaultState, action) {
const handler = reducers[action.type];
if (handler) return handler(state, action);
return state;
}

29
ui/js/selectors/search.js Normal file
View file

@ -0,0 +1,29 @@
import { createSelector } from 'reselect'
export const _selectState = state => state.search || {}
export const selectSearchQuery = createSelector(
_selectState,
(state) => state.query
)
export const selectIsSearching = createSelector(
_selectState,
(state) => !!state.searching
)
export const selectSearchResults = createSelector(
_selectState,
(state) => state.results || {}
)
export const selectSearchResultsByQuery = createSelector(
selectSearchResults,
(results) => results.byQuery || {}
)
export const selectCurrentSearchResults = createSelector(
selectSearchQuery,
selectSearchResultsByQuery,
(query, byQuery) => byQuery[query] || []
)

View file

@ -8,6 +8,7 @@ import {
import appReducer from 'reducers/app'; import appReducer from 'reducers/app';
import contentReducer from 'reducers/content'; import contentReducer from 'reducers/content';
import rewardsReducer from 'reducers/rewards' import rewardsReducer from 'reducers/rewards'
import searchReducer from 'reducers/search'
import walletReducer from 'reducers/wallet' import walletReducer from 'reducers/wallet'
function isFunction(object) { function isFunction(object) {
@ -22,6 +23,7 @@ const reducers = redux.combineReducers({
app: appReducer, app: appReducer,
content: contentReducer, content: contentReducer,
rewards: rewardsReducer, rewards: rewardsReducer,
search: searchReducer,
wallet: walletReducer, wallet: walletReducer,
}); });