diff --git a/src/ui/component/channelContent/view.jsx b/src/ui/component/channelContent/view.jsx index 2d04fab7d..4bb3f2f9e 100644 --- a/src/ui/component/channelContent/view.jsx +++ b/src/ui/component/channelContent/view.jsx @@ -43,7 +43,7 @@ function ChannelContent(props: Props) { {!channelIsMine && } {hasContent && !channelIsBlocked && ( - claim.permanent_url)} /> + claim.canonical_url)} /> )} {!channelIsBlocked && ( )} + + {injectedItem &&
{injectedItem}
} + {urisLength > 0 && (
    {sortedUris.map((uri, index) => ( - - - {index === 4 && injectedItem && injectedItem} - + ))}
)} diff --git a/src/ui/component/claimListDiscover/index.js b/src/ui/component/claimListDiscover/index.js index 7e4f7e5b1..0505c4eec 100644 --- a/src/ui/component/claimListDiscover/index.js +++ b/src/ui/component/claimListDiscover/index.js @@ -2,7 +2,7 @@ import * as SETTINGS from 'constants/settings'; import { connect } from 'react-redux'; import { doClaimSearch, - selectClaimSearchByQuery, + selectClaimSearchByQueryCanonical, selectFetchingClaimSearch, doToggleTagFollow, selectBlockedChannels, @@ -12,7 +12,7 @@ import { makeSelectClientSetting } from 'redux/selectors/settings'; import ClaimListDiscover from './view'; const select = state => ({ - claimSearchByQuery: selectClaimSearchByQuery(state), + claimSearchByQuery: selectClaimSearchByQueryCanonical(state), loading: selectFetchingClaimSearch(state), subscribedChannels: selectSubscriptions(state), showNsfw: makeSelectClientSetting(SETTINGS.SHOW_NSFW)(state), diff --git a/src/ui/component/claimPreview/index.js b/src/ui/component/claimPreview/index.js index 203d81718..c9dfd3965 100644 --- a/src/ui/component/claimPreview/index.js +++ b/src/ui/component/claimPreview/index.js @@ -23,20 +23,20 @@ import { push } from 'connected-react-router'; import ClaimPreview from './view'; const select = (state, props) => ({ - pending: makeSelectClaimIsPending(props.uri)(state), - claim: makeSelectClaimForUri(props.uri)(state), + pending: props.uri && makeSelectClaimIsPending(props.uri)(state), + claim: props.uri && makeSelectClaimForUri(props.uri)(state), obscureNsfw: !selectShowMatureContent(state), - claimIsMine: makeSelectClaimIsMine(props.uri)(state), - isResolvingUri: makeSelectIsUriResolving(props.uri)(state), - thumbnail: makeSelectThumbnailForUri(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), - nsfw: makeSelectClaimIsNsfw(props.uri)(state), + claimIsMine: props.uri && makeSelectClaimIsMine(props.uri)(state), + isResolvingUri: props.uri && makeSelectIsUriResolving(props.uri)(state), + thumbnail: props.uri && makeSelectThumbnailForUri(props.uri)(state), + title: props.uri && makeSelectTitleForUri(props.uri)(state), + nsfw: props.uri && makeSelectClaimIsNsfw(props.uri)(state), blackListedOutpoints: selectBlackListedOutpoints(state), filteredOutpoints: selectFilteredOutpoints(state), blockedChannelUris: selectBlockedChannels(state), - hasVisitedUri: makeSelectHasVisitedUri(props.uri)(state), - channelIsBlocked: selectChannelIsBlocked(props.uri)(state), - isSubscribed: makeSelectIsSubscribed(props.uri, true)(state), + hasVisitedUri: props.uri && makeSelectHasVisitedUri(props.uri)(state), + channelIsBlocked: props.uri && selectChannelIsBlocked(props.uri)(state), + isSubscribed: props.uri && makeSelectIsSubscribed(props.uri, true)(state), }); const perform = dispatch => ({ diff --git a/src/ui/component/claimPreview/view.jsx b/src/ui/component/claimPreview/view.jsx index 93a1bc8cd..4aabcb6b1 100644 --- a/src/ui/component/claimPreview/view.jsx +++ b/src/ui/component/claimPreview/view.jsx @@ -78,13 +78,15 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { const includeChannelTooltip = type !== 'inline' && type !== 'tooltip'; const hideActions = type === 'small' || type === 'tooltip'; - let isValid; let name; - try { - ({ claimName: name } = parseURI(uri)); - isValid = true; - } catch (e) { - isValid = false; + let isValid = false; + if (uri) { + try { + ({ claimName: name } = parseURI(uri)); + isValid = true; + } catch (e) { + isValid = false; + } } const isChannel = isValid ? parseURI(uri).isChannel : false; diff --git a/src/ui/component/claimUri/index.js b/src/ui/component/claimUri/index.js index 85a69cb1a..60e8b720c 100644 --- a/src/ui/component/claimUri/index.js +++ b/src/ui/component/claimUri/index.js @@ -1,9 +1,9 @@ import { connect } from 'react-redux'; -import { makeSelectShortUrlForUri, doToast } from 'lbry-redux'; +import { makeSelectCanonicalUrlForUri, doToast } from 'lbry-redux'; import ClaimUri from './view'; const select = (state, props) => ({ - shortUrl: makeSelectShortUrlForUri(props.uri)(state), + shortUrl: makeSelectCanonicalUrlForUri(props.uri)(state), }); export default connect( diff --git a/src/ui/component/wunderbar/view.jsx b/src/ui/component/wunderbar/view.jsx index 94f8b45e2..d1336485c 100644 --- a/src/ui/component/wunderbar/view.jsx +++ b/src/ui/component/wunderbar/view.jsx @@ -11,6 +11,9 @@ import Tag from 'component/tag'; const L_KEY_CODE = 76; const ESC_KEY_CODE = 27; +const WEB_DEV_PREFIX = 'http://localhost:1337/'; +const WEB_PROD_PREFIX = 'https://beta.lbry.tv/'; +const SEARCH_PREFIX = `$/${PAGES.SEARCH}q=`; type Props = { searchQuery: ?string, @@ -95,12 +98,37 @@ class WunderBar extends React.PureComponent { handleSubmit(value: string, suggestion?: { value: string, type: string }) { const { onSubmit, onSearch, doShowSnackBar, history } = this.props; + let query = value.trim(); - const query = value.trim(); const showSnackError = () => { doShowSnackBar('Invalid LBRY URL entered. Only A-Z, a-z, 0-9, and "-" allowed.'); }; + // Allow copying a lbry.tv url and pasting it into the search bar + const includesLbryTvProd = query.includes(WEB_PROD_PREFIX); + const includesLbryTvDev = query.includes(WEB_DEV_PREFIX); + const wasCopiedFromWeb = includesLbryTvDev || includesLbryTvProd; + + if (wasCopiedFromWeb) { + if (includesLbryTvDev) { + query = query.slice(WEB_DEV_PREFIX.length); + } else { + query = query.slice(WEB_PROD_PREFIX.length); + } + + query = query.replace(/:/g, '#'); + + if (query.includes(SEARCH_PREFIX)) { + query = query.slice(SEARCH_PREFIX.length); + onSearch(query); + return; + } else { + query = `lbry://${query}`; + onSubmit(query); + return; + } + } + // User selected a suggestion if (suggestion) { if (suggestion.type === SEARCH_TYPES.SEARCH) { diff --git a/src/ui/page/show/index.js b/src/ui/page/show/index.js index 7fac09cb0..25f19bf43 100644 --- a/src/ui/page/show/index.js +++ b/src/ui/page/show/index.js @@ -5,26 +5,23 @@ import { makeSelectClaimForUri, makeSelectIsUriResolving, makeSelectTotalPagesForChannel, - buildURI, + normalizeURI, } from 'lbry-redux'; import { selectBlackListedOutpoints } from 'lbryinc'; import ShowPage from './view'; const select = (state, props) => { const { pathname } = props.location; - const urlParts = pathname.split('/'); - const claimName = urlParts[1]; - const claimId = urlParts[2]; - - // claimName and claimId come from the url `lbry.tv/{claimName}/{claimId}" - const uri = buildURI({ contentName: claimName, claimId: claimId }); + // Remove the leading "/" added by the browser + const path = pathname.slice(1).replace(/:/g, '#'); + const uri = normalizeURI(path); return { claim: makeSelectClaimForUri(uri)(state), isResolvingUri: makeSelectIsUriResolving(uri)(state), blackListedOutpoints: selectBlackListedOutpoints(state), totalPages: makeSelectTotalPagesForChannel(uri, PAGE_SIZE)(state), - uri: uri, + uri, }; }; diff --git a/src/ui/scss/component/_claim-list.scss b/src/ui/scss/component/_claim-list.scss index a4ee36bd9..320d0b922 100644 --- a/src/ui/scss/component/_claim-list.scss +++ b/src/ui/scss/component/_claim-list.scss @@ -109,7 +109,7 @@ $border-color--dark: var(--dm-color-04); .claim-preview--injected, .claim-preview { - border-bottom: 1px solid $border-color; + border-top: 1px solid $border-color; &:only-of-type { border: none; diff --git a/src/ui/util/uri.js b/src/ui/util/uri.js index 70d20d765..353008c2e 100644 --- a/src/ui/util/uri.js +++ b/src/ui/util/uri.js @@ -1,17 +1,9 @@ // @flow -import { parseURI } from 'lbry-redux'; const LBRY_INC_DOMAINS = ['lbry.io', 'lbry.com', 'lbry.tv', 'lbry.tech', 'lbry.fund', 'spee.ch']; export const formatLbryUriForWeb = (uri: string) => { - const { claimName, claimId } = parseURI(uri); - - let webUrl = `/${claimName}`; - if (claimId) { - webUrl += `/${claimId}`; - } - - return webUrl; + return uri.replace('lbry://', '/').replace(/#/g, ':'); }; export const formatPathForWeb = (path: string) => {