basic search working on channels
This commit is contained in:
parent
cde543499c
commit
f21087f873
6 changed files with 125 additions and 28 deletions
|
@ -17,9 +17,13 @@ import ClaimUri from 'component/claimUri';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import * as MODALS from 'constants/modal_types';
|
import * as MODALS from 'constants/modal_types';
|
||||||
|
import { Form, FormField } from 'component/common/form';
|
||||||
|
import ClaimPreview from 'component/claimPreview';
|
||||||
|
import Icon from 'component/common/icon';
|
||||||
|
|
||||||
const PAGE_VIEW_QUERY = `view`;
|
const PAGE_VIEW_QUERY = `view`;
|
||||||
const ABOUT_PAGE = `about`;
|
const ABOUT_PAGE = `about`;
|
||||||
|
const LIGHTHOUSE_URL = 'https://lighthouse.lbry.com/search';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
uri: string,
|
uri: string,
|
||||||
|
@ -67,22 +71,47 @@ function ChannelPage(props: Props) {
|
||||||
const [editing, setEditing] = useState(false);
|
const [editing, setEditing] = useState(false);
|
||||||
const [thumbPreview, setThumbPreview] = useState(thumbnail);
|
const [thumbPreview, setThumbPreview] = useState(thumbnail);
|
||||||
const [coverPreview, setCoverPreview] = useState(cover);
|
const [coverPreview, setCoverPreview] = useState(cover);
|
||||||
|
const [searchQuery, setSearchQuery] = useState('');
|
||||||
|
const [searchResults, setSearchResults] = useState(undefined);
|
||||||
|
|
||||||
// If a user changes tabs, update the url so it stays on the same page if they refresh.
|
// If a user changes tabs, update the url so it stays on the same page if they refresh.
|
||||||
// We don't want to use links here because we can't animate the tab change and using links
|
// We don't want to use links here because we can't animate the tab change and using links
|
||||||
// would alter the Tab label's role attribute, which should stay role="tab" to work with keyboards/screen readers.
|
// would alter the Tab label's role attribute, which should stay role="tab" to work with keyboards/screen readers.
|
||||||
const tabIndex = currentView === ABOUT_PAGE || editing ? 1 : 0;
|
const tabIndex = currentView === ABOUT_PAGE || editing ? 1 : 0;
|
||||||
const onTabChange = newTabIndex => {
|
function onTabChange(newTabIndex) {
|
||||||
let url = formatLbryUriForWeb(uri);
|
let url = formatLbryUriForWeb(uri);
|
||||||
let search = '?';
|
let search = '?';
|
||||||
if (newTabIndex !== 0) {
|
if (newTabIndex !== 0) {
|
||||||
search += `${PAGE_VIEW_QUERY}=${ABOUT_PAGE}`;
|
search += `${PAGE_VIEW_QUERY}=${ABOUT_PAGE}`;
|
||||||
} else {
|
} else {
|
||||||
|
setSearchResults(null);
|
||||||
search += `page=${page}`;
|
search += `page=${page}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
history.push(`${url}${search}`);
|
history.push(`${url}${search}`);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
function handleSearch() {
|
||||||
|
const fetchUrl = `${LIGHTHOUSE_URL}?s=${encodeURIComponent(searchQuery)}&channel=${encodeURIComponent(
|
||||||
|
uri.slice('lbry://'.length)
|
||||||
|
)}`;
|
||||||
|
fetch(fetchUrl)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(results => {
|
||||||
|
const urls = results.map(({ name, claimId }) => {
|
||||||
|
return `lbry://${name}#${claimId}`;
|
||||||
|
});
|
||||||
|
setSearchResults(urls);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
setSearchResults(null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleInputChange(e) {
|
||||||
|
const { value } = e.target;
|
||||||
|
setSearchQuery(value);
|
||||||
|
}
|
||||||
|
|
||||||
let channelIsBlackListed = false;
|
let channelIsBlackListed = false;
|
||||||
|
|
||||||
|
@ -96,6 +125,29 @@ function ChannelPage(props: Props) {
|
||||||
<Page>
|
<Page>
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<header className="channel-cover">
|
<header className="channel-cover">
|
||||||
|
<div className="channel__quick-actions">
|
||||||
|
{!channelIsBlocked && !channelIsBlackListed && <ShareButton uri={uri} />}
|
||||||
|
{!channelIsMine && (
|
||||||
|
<Button
|
||||||
|
button="alt"
|
||||||
|
icon={ICONS.TIP}
|
||||||
|
label={__('Tip')}
|
||||||
|
title={__('Send a tip to this creator')}
|
||||||
|
onClick={() => openModal(MODALS.SEND_TIP, { uri, channelIsMine, isSupport: false })}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{(channelIsMine || (!channelIsMine && supportOption)) && (
|
||||||
|
<Button
|
||||||
|
button="alt"
|
||||||
|
icon={ICONS.SUPPORT}
|
||||||
|
label={__('Support')}
|
||||||
|
title={__('Support this creator')}
|
||||||
|
onClick={() => openModal(MODALS.SEND_TIP, { uri, channelIsMine, isSupport: true })}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{!channelIsBlocked && !channelIsBlackListed && <SubscribeButton uri={permanentUrl} />}
|
||||||
|
{!isSubscribed && <BlockButton uri={permanentUrl} />}
|
||||||
|
</div>
|
||||||
{!editing && cover && (
|
{!editing && cover && (
|
||||||
<img
|
<img
|
||||||
className={classnames('channel-cover__custom', { 'channel__image--blurred': channelIsBlocked })}
|
className={classnames('channel-cover__custom', { 'channel__image--blurred': channelIsBlocked })}
|
||||||
|
@ -130,34 +182,25 @@ function ChannelPage(props: Props) {
|
||||||
<TabList className="tabs__list--channel-page">
|
<TabList className="tabs__list--channel-page">
|
||||||
<Tab disabled={editing}>{__('Content')}</Tab>
|
<Tab disabled={editing}>{__('Content')}</Tab>
|
||||||
<Tab>{editing ? __('Editing Your Channel') : __('About')}</Tab>
|
<Tab>{editing ? __('Editing Your Channel') : __('About')}</Tab>
|
||||||
<div className="card__actions--inline">
|
<Form onSubmit={handleSearch} className="wunderbar--channel">
|
||||||
{!channelIsBlocked && !channelIsBlackListed && <ShareButton uri={uri} />}
|
<Icon icon={ICONS.SEARCH} />
|
||||||
{!channelIsMine && (
|
<FormField
|
||||||
<Button
|
className="wunderbar__input"
|
||||||
button="alt"
|
value={searchQuery}
|
||||||
icon={ICONS.TIP}
|
onChange={handleInputChange}
|
||||||
label={__('Tip')}
|
type="text"
|
||||||
title={__('Send a tip to this creator')}
|
placeholder={__('Search')}
|
||||||
onClick={() => openModal(MODALS.SEND_TIP, { uri, channelIsMine, isSupport: false })}
|
|
||||||
/>
|
/>
|
||||||
)}
|
</Form>
|
||||||
{(channelIsMine || (!channelIsMine && supportOption)) && (
|
|
||||||
<Button
|
|
||||||
button="alt"
|
|
||||||
icon={ICONS.SUPPORT}
|
|
||||||
label={__('Support')}
|
|
||||||
title={__('Support this creator')}
|
|
||||||
onClick={() => openModal(MODALS.SEND_TIP, { uri, channelIsMine, isSupport: true })}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
{!channelIsBlocked && !channelIsBlackListed && <SubscribeButton uri={permanentUrl} />}
|
|
||||||
{!isSubscribed && <BlockButton uri={permanentUrl} />}
|
|
||||||
</div>
|
|
||||||
</TabList>
|
</TabList>
|
||||||
|
|
||||||
<TabPanels>
|
<TabPanels>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
|
{searchResults ? (
|
||||||
|
searchResults.map(url => <ClaimPreview key={url} uri={url} />)
|
||||||
|
) : (
|
||||||
<ChannelContent uri={uri} channelIsBlackListed={channelIsBlackListed} />
|
<ChannelContent uri={uri} channelIsBlackListed={channelIsBlackListed} />
|
||||||
|
)}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
{editing ? (
|
{editing ? (
|
||||||
|
|
|
@ -106,3 +106,11 @@ $metadata-z-index: 1;
|
||||||
.channel__image--blurred {
|
.channel__image--blurred {
|
||||||
filter: blur(16px);
|
filter: blur(16px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.channel__quick-actions {
|
||||||
|
@extend .card__actions;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: var(--spacing-medium);
|
||||||
|
z-index: $metadata-z-index;
|
||||||
|
}
|
||||||
|
|
|
@ -320,3 +320,21 @@ fieldset-section {
|
||||||
.form-field--address {
|
.form-field--address {
|
||||||
width: 370px;
|
width: 370px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-field--channel-search {
|
||||||
|
&:not(:last-child) {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
&:not(:hover) {
|
||||||
|
border: 1px solid $lbry-gray-5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid $lbry-white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -20,9 +20,17 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
stroke: $lbry-gray-5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.wunderbar--channel {
|
||||||
|
@extend .wunderbar;
|
||||||
|
flex: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
color: $lbry-black;
|
||||||
|
}
|
||||||
|
|
||||||
.wunderbar__active-suggestion {
|
.wunderbar__active-suggestion {
|
||||||
background-color: lighten($lbry-blue-1, 15%);
|
background-color: lighten($lbry-blue-1, 15%);
|
||||||
color: $lbry-black;
|
color: $lbry-black;
|
||||||
|
|
|
@ -623,5 +623,25 @@
|
||||||
"Find New Tags": "Find New Tags",
|
"Find New Tags": "Find New Tags",
|
||||||
"View File": "View File",
|
"View File": "View File",
|
||||||
"Close": "Close",
|
"Close": "Close",
|
||||||
"% downloaded": "% downloaded"
|
"% downloaded": "% downloaded",
|
||||||
|
"View Tag": "View Tag",
|
||||||
|
"Nothing here": "Nothing here",
|
||||||
|
"Publish something and claim this spot!": "Publish something and claim this spot!",
|
||||||
|
"Publish to": "Publish to",
|
||||||
|
"Network and Data Settings": "Network and Data Settings",
|
||||||
|
"Save all viewed content to your downloads directory": "Save all viewed content to your downloads directory",
|
||||||
|
"Paid content and some file types are saved by default. Changing this setting will not affect previously downloaded content.": "Paid content and some file types are saved by default. Changing this setting will not affect previously downloaded content.",
|
||||||
|
"Save hosting data to help the LBRY network": "Save hosting data to help the LBRY network",
|
||||||
|
"If disabled, LBRY will be very sad and you won't be helping improve the network.": "If disabled, LBRY will be very sad and you won't be helping improve the network.",
|
||||||
|
"Floating video player": "Floating video player",
|
||||||
|
"Keep content playing in the corner when navigating to a different page.": "Keep content playing in the corner when navigating to a different page.",
|
||||||
|
"Blocked Channels": "Blocked Channels",
|
||||||
|
"blocked": "blocked",
|
||||||
|
"channels": "channels",
|
||||||
|
"Manage": "Manage",
|
||||||
|
"Automatic dark mode": "Automatic dark mode",
|
||||||
|
"Hide wallet balance in header": "Hide wallet balance in header",
|
||||||
|
"Max Connections": "Max Connections",
|
||||||
|
"For users with good bandwidth, try a higher value to improve streaming and download speeds. Low bandwidth users may benefit from a lower setting. Default is 4.": "For users with good bandwidth, try a higher value to improve streaming and download speeds. Low bandwidth users may benefit from a lower setting. Default is 4.",
|
||||||
|
"This will clear the application cache. Your wallet will not be affected. Currently, followed tags and blocked channels will be cleared.": "This will clear the application cache. Your wallet will not be affected. Currently, followed tags and blocked channels will be cleared."
|
||||||
}
|
}
|
Loading…
Reference in a new issue