From 9f9d0a651b55ec8894878036b83efb567ba75512 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Sat, 19 Jun 2021 16:28:00 +0800 Subject: [PATCH] Moderation: resolve chan name or URL instead of using Lighthouse. While Lighthouse allows looser searching like "Tom from LBRY", it doesn't show the expected results when direct channel name with partial ID is entered to disambiguate. --- static/app-strings.json | 2 + ui/component/claimPreview/view.jsx | 8 ++- ui/page/settingsCreator/view.jsx | 89 ++++++++++++++++++++++++------ ui/util/search.js | 70 +++++++++++++++++++++++ 4 files changed, 149 insertions(+), 20 deletions(-) diff --git a/static/app-strings.json b/static/app-strings.json index 390d654ff..8737ec4a2 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -1911,6 +1911,7 @@ "Enabling a minimum amount to hyperchat will force all TIPPED comments to have this value in order to be shown. This still allows regular comments to be posted.": "Enabling a minimum amount to hyperchat will force all TIPPED comments to have this value in order to be shown. This still allows regular comments to be posted.", "Settings unavailable for this channel": "Settings unavailable for this channel", "This channel isn't staking enough LBRY Credits to enable Creator Settings.": "This channel isn't staking enough LBRY Credits to enable Creator Settings.", + "Not a channel (prefix with \"@\", or enter the channel URL)": "Not a channel (prefix with \"@\", or enter the channel URL)", "We apologize for this inconvenience, but have added this additional step to prevent abuse. Users on VPN or shared connections will continue to see this message and are not eligible for Rewards.": "We apologize for this inconvenience, but have added this additional step to prevent abuse. Users on VPN or shared connections will continue to see this message and are not eligible for Rewards.", "Help LBRY Save Crypto": "Help LBRY Save Crypto", "The US government is attempting to destroy the cryptocurrency industry. Can you help?": "The US government is attempting to destroy the cryptocurrency industry. Can you help?", @@ -1994,5 +1995,6 @@ "Item added to Watch Later": "Item added to Watch Later", "Your publish is being confirmed and will be live soon": "Your publish is being confirmed and will be live soon", "Clear Edits": "Clear Edits", + "Something not quite right..": "Something not quite right..", "--end--": "--end--" } diff --git a/ui/component/claimPreview/view.jsx b/ui/component/claimPreview/view.jsx index 835f35b43..a69742968 100644 --- a/ui/component/claimPreview/view.jsx +++ b/ui/component/claimPreview/view.jsx @@ -78,6 +78,7 @@ type Props = { isCollectionMine: boolean, collectionUris: Array, collectionIndex?: number, + disableNavigation?: boolean, }; const ClaimPreview = forwardRef((props: Props, ref: any) => { @@ -134,6 +135,7 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { editCollection, isCollectionMine, collectionUris, + disableNavigation, } = props; const isRepost = claim && claim.repost_channel_url; const WrapperElement = wrapperElement || 'li'; @@ -214,7 +216,7 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { onClick(e); } - if (claim && !pending) { + if (claim && !pending && !disableNavigation) { history.push(navigateUrl); } } @@ -423,7 +425,9 @@ const ClaimPreview = forwardRef((props: Props, ref: any) => { )} - {!hideMenu && } + {!hideMenu && ( + + )} ); diff --git a/ui/page/settingsCreator/view.jsx b/ui/page/settingsCreator/view.jsx index cf8b5d5c8..c89a662b2 100644 --- a/ui/page/settingsCreator/view.jsx +++ b/ui/page/settingsCreator/view.jsx @@ -3,13 +3,15 @@ import * as React from 'react'; import Card from 'component/common/card'; import TagsSearch from 'component/tagsSearch'; import Page from 'component/page'; +import Button from 'component/button'; import ChannelSelector from 'component/channelSelector'; import Spinner from 'component/spinner'; import { FormField } from 'component/common/form-components/form-field'; import LbcSymbol from 'component/common/lbc-symbol'; import I18nMessage from 'component/i18nMessage'; -import { parseURI } from 'lbry-redux'; -import WunderBar from 'component/wunderbar'; +import { isNameValid, parseURI } from 'lbry-redux'; +import ClaimPreview from 'component/claimPreview'; +import { getUriForSearchTerm } from 'util/search'; const DEBOUNCE_REFRESH_MS = 1000; @@ -49,6 +51,9 @@ export default function SettingsCreatorPage(props: Props) { const [commentsEnabled, setCommentsEnabled] = React.useState(true); const [mutedWordTags, setMutedWordTags] = React.useState([]); const [moderatorTags, setModeratorTags] = React.useState([]); + const [moderatorSearchTerm, setModeratorSearchTerm] = React.useState(''); + const [moderatorSearchError, setModeratorSearchError] = React.useState(''); + const [moderatorSearchClaimUri, setModeratorSearchClaimUri] = React.useState(''); const [minTipAmountComment, setMinTipAmountComment] = React.useState(0); const [minTipAmountSuperChat, setMinTipAmountSuperChat] = React.useState(0); const [slowModeMinGap, setSlowModeMinGap] = React.useState(0); @@ -142,17 +147,39 @@ export default function SettingsCreatorPage(props: Props) { } } - function handleChannelSearchSelect(value: string) { - let uriInfo; - try { - uriInfo = parseURI(value); - } catch (e) {} - - if (uriInfo && uriInfo.path) { - addModerator([{ name: uriInfo.path }]); + function handleChannelSearchSelect(claim) { + if (claim && claim.name && claim.claim_id) { + addModerator([{ name: claim.name + '#' + claim.claim_id }]); } } + // 'moderatorSearchTerm' to 'moderatorSearchClaimUri' + React.useEffect(() => { + if (!moderatorSearchTerm) { + setModeratorSearchError(''); + setModeratorSearchClaimUri(''); + } else { + const [searchUri, error] = getUriForSearchTerm(moderatorSearchTerm); + setModeratorSearchError(error ? __('Something not quite right..') : ''); + + try { + const { streamName, channelName, isChannel } = parseURI(searchUri); + + if (!isChannel && streamName && isNameValid(streamName)) { + setModeratorSearchError(__('Not a channel (prefix with "@", or enter the channel URL)')); + setModeratorSearchClaimUri(''); + } else if (isChannel && channelName && isNameValid(channelName)) { + setModeratorSearchClaimUri(searchUri); + } + } catch (e) { + if (moderatorSearchTerm !== '@') { + setModeratorSearchError(''); + } + setModeratorSearchClaimUri(''); + } + } + }, [moderatorSearchTerm, setModeratorSearchError]); + // Update local moderator states with data from API. React.useEffect(() => { commentModListDelegates(activeChannelClaim); @@ -318,18 +345,44 @@ export default function SettingsCreatorPage(props: Props) { className="card--enable-overflow" actions={
- - setModeratorSearchTerm(e.target.value)} + error={moderatorSearchError} /> + {moderatorSearchClaimUri && ( +
+ { + return ( +
+ )} { + return term.startsWith('lbry://') ? term : `lbry://${term}`; + }; + + if (wasCopiedFromWeb) { + let prefix = WEB_PROD_PREFIX; + if (includesLbryTvLocal) prefix = WEB_LOCAL_PREFIX; + if (includesLbryTvDev) prefix = WEB_DEV_PREFIX; + if (includesOdysee) prefix = ODYSEE_PREFIX; + + let query = (term && term.slice(prefix.length).replace(/:/g, '#')) || ''; + try { + const lbryUrl = `lbry://${query}`; + parseURI(lbryUrl); + return [lbryUrl, null]; + } catch (e) { + return [query, 'error']; + } + } + + if (!isLbryUrl) { + if (term.startsWith('@')) { + if (isNameValid(term.slice(1))) { + return [term, null]; + } else { + return [term, error]; + } + } + return [addLbryIfNot(term), null]; + } else { + try { + const isValid = isURIValid(term); + if (isValid) { + let uri; + try { + uri = normalizeURI(term); + } catch (e) { + return [term, null]; + } + return [uri, null]; + } else { + return [term, null]; + } + } catch (e) { + return [term, 'error']; + } + } +}