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 lbry from 'lbry'
import lbryio from 'lbryio';
import lbryio from 'lbryio'
import {
selectCurrentUri,
} from 'selectors/app'
import {
selectSearchTerm,
} from 'selectors/content'
import {
selectCurrentResolvedUriClaimOutpoint,
} 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 {
doNavigate,
} from 'actions/app'
import {
doSearchContent,
} from 'actions/search'
import Header from './view'
const select = (state) => ({
@ -18,6 +21,7 @@ const select = (state) => ({
const perform = (dispatch) => ({
navigate: (path) => dispatch(doNavigate(path)),
search: (query) => dispatch(doSearchContent(query)),
})
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_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'
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 {
selectFeaturedContentByCategory
} from 'selectors/content'
import {
doSearchContent,
} from 'actions/search'
import {
selectIsSearching,
selectSearchQuery,
selectCurrentSearchResults,
} from 'selectors/search'
import DiscoverPage from './view'
const select = (state) => ({
featuredContentByCategory: selectFeaturedContentByCategory(state),
isSearching: selectIsSearching(state),
query: selectSearchQuery(state),
results: selectCurrentSearchResults(state),
})
const perform = (dispatch) => ({

View file

@ -14,7 +14,7 @@ const FeaturedCategory = (props) => {
resolvedUris,
names,
} = props
return <div className="card-row card-row--small">
<h3 className="card-row__header">{category}
{category && category.match(/^community/i) && <ToolTip label="What's this?" body={communityCategoryToolTipText} className="tooltip--header" />}
@ -60,6 +60,6 @@ let DiscoverPage = React.createClass({
</div>
}</main>;
}
});
})
export default DiscoverPage;

View file

@ -2,7 +2,7 @@ import React from 'react';
import lbry from 'lbry.js';
import lighthouse from 'lighthouse.js';
import lbryuri from 'lbryuri.js';
import {Video} from 'page/watch.js'
import Video from 'page/video'
import {
TruncatedText,
Thumbnail,
@ -13,37 +13,44 @@ import {FileActions} from 'component/file-actions.js';
import Link from 'component/link';
import UriIndicator from 'component/channel-indicator.js';
var FormatItem = React.createClass({
propTypes: {
metadata: React.PropTypes.object,
contentType: React.PropTypes.string,
uri: React.PropTypes.string,
outpoint: React.PropTypes.string,
},
render: function() {
const {thumbnail, author, title, description, language, license} = this.props.metadata;
const mediaType = lbry.getMediaType(this.props.contentType);
const FormatItem = (props) => {
const {
contentType,
metadata,
cost,
uri,
outpoint,
costIncludesData,
} = props
const {
thumbnail,
author,
title,
description,
language,
license
} = metadata;
const mediaType = lbry.getMediaType(contentType);
return (
<table className="table-standard">
<tbody>
<tr>
<td>Content-Type</td><td>{this.props.contentType}</td>
</tr>
<tr>
<td>Author</td><td>{author}</td>
</tr>
<tr>
<td>Language</td><td>{language}</td>
</tr>
<tr>
<td>License</td><td>{license}</td>
</tr>
</tbody>
</table>
);
}
});
return (
<table className="table-standard">
<tbody>
<tr>
<td>Content-Type</td><td>{contentType}</td>
</tr>
<tr>
<td>Author</td><td>{author}</td>
</tr>
<tr>
<td>Language</td><td>{language}</td>
</tr>
<tr>
<td>License</td><td>{license}</td>
</tr>
</tbody>
</table>
)
}
let ChannelPage = React.createClass({
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 contentReducer from 'reducers/content';
import rewardsReducer from 'reducers/rewards'
import searchReducer from 'reducers/search'
import walletReducer from 'reducers/wallet'
function isFunction(object) {
@ -22,6 +23,7 @@ const reducers = redux.combineReducers({
app: appReducer,
content: contentReducer,
rewards: rewardsReducer,
search: searchReducer,
wallet: walletReducer,
});