remove channelTooltip component

This commit is contained in:
btzr-io 2019-06-24 10:56:37 -06:00
parent fdd755d83b
commit aa60d99fcd
7 changed files with 6 additions and 377 deletions

View file

@ -1,32 +0,0 @@
import { connect } from 'react-redux';
import {
doResolveUri,
makeSelectTitleForUri,
makeSelectThumbnailForUri,
makeSelectClaimForUri,
makeSelectIsUriResolving,
makeSelectMetadataItemForUri,
} from 'lbry-redux';
import ChannelTooltip from './view';
const select = (state, props) => {
return {
uri: props.uri,
claim: makeSelectClaimForUri(props.uri)(state),
title: makeSelectTitleForUri(props.uri)(state),
thumbnail: makeSelectThumbnailForUri(props.uri)(state),
description: makeSelectMetadataItemForUri(props.uri, 'description')(state),
isResolvingUri: makeSelectIsUriResolving(props.uri)(state),
};
};
const perform = dispatch => ({
resolveUri: uri => dispatch(doResolveUri(uri)),
});
export default connect(
select,
perform
)(ChannelTooltip);

View file

@ -1,41 +0,0 @@
// Defualt function used by reach-ui tooltip componment,
// slightly modify to register current direction:
// https://github.com/reach/reach-ui/blob/f0c8c5c467be46c202148ee69b1ba789b57d5e60/packages/tooltip/src/index.js#L478
// feels awkward when it's perfectly aligned w/ the trigger
const OFFSET = 8;
const positionDefault = (triggerRect, tooltipRect, currentDirection, setDirection) => {
const styles = {
left: `${triggerRect.left + window.pageXOffset}px`,
top: `${triggerRect.top + triggerRect.height + window.pageYOffset}px`,
};
const collisions = {
top: triggerRect.top - tooltipRect.height < 0,
right: window.innerWidth < triggerRect.left + tooltipRect.width,
bottom: window.innerHeight < triggerRect.bottom + tooltipRect.height + OFFSET,
left: triggerRect.left - tooltipRect.width < 0,
};
const directionRight = collisions.right && !collisions.left;
const directionUp = collisions.bottom && !collisions.top;
const direction = directionUp ? 'top' : 'bottom';
if (direction !== currentDirection) {
setDirection(direction);
}
return {
...styles,
left: directionRight
? `${triggerRect.right - tooltipRect.width + window.pageXOffset}px`
: `${triggerRect.left + window.pageXOffset}px`,
top: directionUp
? `${triggerRect.top - OFFSET - tooltipRect.height + window.pageYOffset}px`
: `${triggerRect.top + OFFSET + triggerRect.height + window.pageYOffset}px`,
};
};
export default positionDefault;

View file

@ -1,173 +0,0 @@
// @flow
import * as React from 'react';
import classnames from 'classnames';
import ChannelThumbnail from 'component/channelThumbnail';
import TruncatedText from 'component/common/truncated-text';
// Tooltip components
import Portal from '@reach/portal';
import getPostion from './position.js';
import { useTooltip, TooltipPopup } from '@reach/tooltip';
// Tooltip base styles
import '@reach/tooltip/styles.css';
const ARROW_SIZE = 10;
type ChannelTooltipProps = {
uri: string,
claim: ?Claim,
title: ?string,
children: any,
resolveUri: string => void,
description: ?string,
isResolvingUri: boolean,
};
type LabelProps = {
uri: string,
title: ?string,
claimId: string,
channelName: string,
description: ?string,
};
type TriangleTooltipProps = {
label: any,
children: any,
ariaLabel: ?string,
};
function TriangleTooltip(props: TriangleTooltipProps) {
const { label, children, ariaLabel } = props;
// get the props from useTooltip
const [trigger, tooltip] = useTooltip();
// Tooltip direction
const [direction, setDirection] = React.useState('bottom');
// destructure off what we need to position the triangle
const { isVisible, triggerRect } = tooltip;
let arrowTop;
// Top
if (direction === 'top') {
arrowTop = triggerRect && triggerRect.bottom - (triggerRect.height + ARROW_SIZE) + window.scrollY;
}
// Bottom
if (direction === 'bottom') {
arrowTop = triggerRect && triggerRect.bottom + window.scrollY;
}
return (
<React.Fragment>
{React.cloneElement(children, trigger)}
{isVisible && (
// The Triangle. We position it relative to the trigger, not the popup
// so that collisions don't have a triangle pointing off to nowhere.
// Using a Portal may seem a little extreme, but we can keep the
// positioning logic simpler here instead of needing to consider
// the popup's position relative to the trigger and collisions
<Portal>
<span
className={classnames('channel-tooltip__arrow', `channel-tooltip__arrow--${direction}`)}
style={{
position: 'absolute',
top: arrowTop,
left: triggerRect && triggerRect.left - ARROW_SIZE + triggerRect.width / 2,
}}
/>
</Portal>
)}
<TooltipPopup
{...tooltip}
label={label}
ariaLabel={ariaLabel}
className={'channel-tooltip'}
position={(triggerRect, tooltipRect) => getPostion(triggerRect, tooltipRect, direction, setDirection)}
/>
</React.Fragment>
);
}
const ChannelTooltipLabel = (props: LabelProps) => {
const { uri, title, claimId, description, channelName } = props;
const channelUrl = `${channelName}#${claimId}`;
const formatedName = channelName.replace('@', '');
return (
<div className={'channel-tooltip__content'}>
<div className={'channel-tooltip__profile'}>
<ChannelThumbnail uri={uri} />
<div className={'channel-tooltip__info'}>
<h2 className={'channel-tooltip__title'}>
<TruncatedText lines={1}>{title || formatedName}</TruncatedText>
</h2>
<h3 className={'channel-tooltip__url'}>
<TruncatedText lines={1}>{channelUrl}</TruncatedText>
</h3>
</div>
</div>
{description && (
<div className={'channel-tooltip__description'}>
<div>
<TruncatedText lines={2}>{description}</TruncatedText>
</div>
</div>
)}
<div className={'channel-tooltip__stats'} />
</div>
);
};
class ChannelTooltip extends React.Component<ChannelTooltipProps> {
componentDidMount() {
this.resolve(this.props);
}
componentDidUpdate() {
this.resolve(this.props);
}
resolve = (props: ChannelTooltipProps) => {
const { isResolvingUri, resolveUri, claim, uri } = props;
if (!isResolvingUri && claim === undefined && uri) {
resolveUri(uri);
}
};
render() {
const { uri, claim, children, title, description } = this.props;
if (!uri || !claim) {
return children;
}
const { claim_id: claimId, name: channelName } = claim;
// Generate aria-label
const ariaLabel = title || channelName;
const label = (
<ChannelTooltipLabel
uri={uri}
title={title}
claimId={claimId}
channelName={channelName}
description={description}
/>
);
return (
<TriangleTooltip label={label} ariaLabel={ariaLabel}>
{children}
</TriangleTooltip>
);
}
}
export default ChannelTooltip;

View file

@ -2,12 +2,9 @@
import * as React from 'react'; import * as React from 'react';
import Button from 'component/button'; import Button from 'component/button';
import PreviewLink from 'component/previewLink'; import PreviewLink from 'component/previewLink';
import ChannelTooltip from 'component/channelTooltip';
import { parseURI } from 'lbry-redux';
type Props = { type Props = {
uri: string, uri: string,
link?: boolean,
title: ?string, title: ?string,
claim: StreamClaim, claim: StreamClaim,
children: React.Node, children: React.Node,
@ -67,7 +64,7 @@ class ClaimLink extends React.Component<Props> {
}; };
render() { render() {
const { uri, link, claim, title, className, autoEmbed, children, isResolvingUri } = this.props; const { uri, claim, title, className, autoEmbed, children, isResolvingUri } = this.props;
const isUnresolved = (!isResolvingUri && !claim) || !claim; const isUnresolved = (!isResolvingUri && !claim) || !claim;
const isBlacklisted = this.isClaimBlackListed(); const isBlacklisted = this.isClaimBlackListed();
@ -76,29 +73,11 @@ class ClaimLink extends React.Component<Props> {
} }
const { name: claimName } = claim; const { name: claimName } = claim;
const { isChannel, path } = parseURI(uri);
const isChannelClaim = isChannel && !path;
const showPreview = autoEmbed === true && !isUnresolved; const showPreview = autoEmbed === true && !isUnresolved;
const innerContent = (
<Button
label={children}
title={!isChannelClaim ? title || claimName : undefined}
button={link ? 'link' : undefined}
className={className}
navigate={uri}
/>
);
const wrappedLink = (
<ChannelTooltip uri={uri}>
<span>{innerContent}</span>
</ChannelTooltip>
);
return ( return (
<React.Fragment> <React.Fragment>
{isChannelClaim ? wrappedLink : innerContent} <Button label={children} title={title || claimName} button={'link'} navigate={uri} className={className} />
{showPreview && <PreviewLink uri={uri} />} {showPreview && <PreviewLink uri={uri} />}
</React.Fragment> </React.Fragment>
); );

View file

@ -44,7 +44,7 @@ class ExternalLink extends React.PureComponent<Props> {
// Return local link if protocol is lbry uri // Return local link if protocol is lbry uri
if (protocol && protocol[0] === 'lbry:' && isURIValid(href)) { if (protocol && protocol[0] === 'lbry:' && isURIValid(href)) {
element = ( element = (
<ClaimLink uri={href} autoEmbed={embed} link> <ClaimLink uri={href} autoEmbed={embed}>
{children} {children}
</ClaimLink> </ClaimLink>
); );

View file

@ -1,6 +1,6 @@
// @flow // @flow
import React from 'react'; import React from 'react';
import ClaimLink from 'component/claimLink'; import Button from 'component/button';
import { buildURI } from 'lbry-redux'; import { buildURI } from 'lbry-redux';
type Props = { type Props = {
@ -60,9 +60,9 @@ class UriIndicator extends React.PureComponent<Props> {
} }
return ( return (
<ClaimLink uri={channelLink} className={'button--uri-indicator'}> <Button className="button--uri-indicator" navigate={channelLink}>
{inner} {inner}
</ClaimLink> </Button>
); );
} else { } else {
return null; return null;

View file

@ -150,107 +150,3 @@
margin-left: -5px; margin-left: -5px;
} }
} }
// Channel-tooltip
.channel-tooltip {
color: $lbry-black;
background-color: $lbry-white;
width: 20rem;
border: none;
border-radius: var(--card-radius);
z-index: 2;
html[data-mode='dark'] & {
color: mix($lbry-white, $lbry-gray-3, 50%);
background-color: mix($lbry-black, $lbry-gray-3, 90%);
}
box-shadow: 0px 2px 10px -2px black;
}
.channel-tooltip__content {
width: 100%;
margin: 0;
display: block;
word-break: break-all;
word-wrap: break-word;
white-space: pre-wrap;
.channel-thumbnail {
left: 0;
position: relative;
flex-shrink: 0;
text-align: center;
display: flex;
max-width: 5rem;
max-height: 5rem;
margin-right: 1rem;
box-shadow: 0px 2px 10px -2px $lbry-black;
}
}
.channel-tooltip__arrow {
width: 0;
height: 0;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
html[data-mode='dark'] & {
z-index: 3;
}
}
.channel-tooltip__arrow--top {
border-top: 10px solid $lbry-gray-5;
border-bottom: 0;
html[data-mode='dark'] & {
z-index: 3;
border-top: 10px solid mix($lbry-black, $lbry-gray-3, 90%);
border-bottom: 0;
}
}
.channel-tooltip__arrow--bottom {
border-top: 0;
border-bottom: 10px solid $lbry-gray-5;
html[data-mode='dark'] & {
z-index: 3;
border-top: 0;
border-bottom: 10px solid mix($lbry-black, $lbry-gray-3, 90%);
}
}
.channel-tooltip__profile {
display: flex;
align-items: center;
padding: 1rem;
}
.channel-tooltip__description {
padding: 1rem;
visibility: visible;
border-top: 1px solid rgba($lbry-gray-4, 0.4);
width: 100%;
html[data-mode='dark'] & {
border-top: 1px solid rgba($lbry-black, 0.8);
}
}
.channel-tooltip__info {
}
.channel-tooltip__title {
font-weight: bold;
font-size: 1.4rem;
line-height: 1.5em;
visibility: visible;
}
.channel-tooltip__url {
font-size: 1rem;
visibility: visible;
}