Added links/PreviewCardItem to Search feature results

• Added:
- links/PreviewCardItem to Search feature results
This commit is contained in:
mgabdev 2020-10-31 18:31:12 -05:00
parent 7887bc21bc
commit 68fe383a28
2 changed files with 142 additions and 7 deletions

@ -0,0 +1,107 @@
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { fetchLinkCard } from '../actions/links'
import { CX } from '../constants'
import {
decodeIDNA,
getHostname,
trim,
} from '../utils/urls'
import DotTextSeperator from './dot_text_seperator'
import Text from './text'
import Button from './button'
import Image from './image'
import RelativeTimestamp from './relative_timestamp'
class PreviewCardItem extends ImmutablePureComponent {
componentDidMount() {
const { id, card } = this.props
if (!!id && !card) {
this.props.dispatch(fetchLinkCard(id))
}
}
componentDidUpdate(prevProps) {
if (prevProps.id !== this.props.id && !this.props.card) {
this.props.dispatch(fetchLinkCard(this.props.id))
}
}
render() {
const { id, card } = this.props
if (!card) return null
const title = card.get('title')
const maxDescription = 120
const description = trim(card.get('description') || '', maxDescription)
const image = card.get('image')
const website = card.get('url')
const provider = card.get('provider_name').length === 0 ? decodeIDNA(getHostname(card.get('url'))) : card.get('provider_name')
return (
<Button
noClasses
to={`/links/${id}`}
className={[_s.d, _s.px10, _s.mb10, _s.noUnderline].join(' ')}
>
<div className={[_s.d, _s.w100PC, _s.flexRow, _s.px15, _s.py15, _s.boxShadowBlock, _s.bgPrimary, _s.overflowHidden, _s.radiusSmall, _s.bgSubtle_onHover].join(' ')}>
{
!!image &&
<Image
width='110px'
height='110px'
alt={'title'}
src={image}
className={[_s.radiusSmall, _s.overflowHidden, _s.mr10].join(' ')}
/>
}
<div className={[_s.d, _s.flexNormal].join(' ')}>
<div className={_s.d}>
<Text size='medium' color='primary' weight='bold'>
{title}
</Text>
</div>
<div className={[_s.d, _s.maxH40PX, _s.overflowHidden, _s.pt5, _s.mb5].join(' ')}>
<Text size='small' color='secondary'>
{description}
</Text>
</div>
<Text size='small' color='secondary'>
{provider}
</Text>
<div className={[_s.d, _s.flexRow, _s.pt5].join(' ')}>
<Text color='secondary' size='small'>
<RelativeTimestamp timestamp={new Date('10-20-2020')} />
</Text>
</div>
</div>
</div>
</Button>
)
}
}
const mapStateToProps = (state, { id }) => ({
card: state.getIn(['links', 'items', `${id}`]),
isLoading: state.getIn(['links', 'isLoading']),
isError: state.getIn(['links', 'isError']),
})
PreviewCardItem.propTypes = {
card: ImmutablePropTypes.map,
id: PropTypes.string.isRequired,
isLoading: PropTypes.bool.isRequired,
isError: PropTypes.bool.isRequired,
}
export default connect(mapStateToProps)(PreviewCardItem)

@ -14,6 +14,7 @@ import PanelLayout from '../components/panel/panel_layout'
import ColumnIndicator from '../components/column_indicator'
import StatusContainer from '../containers/status_container'
import Block from '../components/block'
import PreviewCardItem from '../components/preview_card_item'
class Search extends ImmutablePureComponent {
@ -37,7 +38,7 @@ class Search extends ImmutablePureComponent {
if (isError) {
return (
<ResponsiveClassesComponent classNamesXS={_s.px10}>
<ResponsiveClassesComponent classNamesXS={[_s.px10, _s.pt15].join(' ')}>
<Block>
<ColumnIndicator type='error' message='Error fetching search results.' />
</Block>
@ -47,7 +48,7 @@ class Search extends ImmutablePureComponent {
if ((results.isEmpty() && isSmallScreen) || (!submitted && results.isEmpty())) {
return (
<ResponsiveClassesComponent classNamesXS={_s.px10}>
<ResponsiveClassesComponent classNamesXS={[_s.px10, _s.pt15].join(' ')}>
<Block>
<div className={[_s.d, _s.py15, _s.px15].join(' ')}>
<Text>Type in the box above and submit to perform a search.</Text>
@ -62,12 +63,13 @@ class Search extends ImmutablePureComponent {
const showHashtags = pathname === '/search/hashtags'
const showGroups = pathname === '/search/groups'
const showStatuses = pathname === '/search/statuses'
const isTop = !showPeople && !showHashtags && !showGroups && !showStatuses
const showLinks = pathname === '/search/links'
const isTop = !showPeople && !showHashtags && !showGroups && !showStatuses && !showLinks
const theLimit = 4
let accounts, statuses, hashtags, groups
let accounts, statuses, hashtags, groups, links
// : todo : statuses
console.log('hello:', results)
if (results.get('accounts') && results.get('accounts').size > 0 && (isTop || showPeople)) {
const size = isTop ? Math.min(results.get('accounts').size, theLimit) : results.get('accounts').size;
@ -165,6 +167,31 @@ class Search extends ImmutablePureComponent {
)
}
if (results.get('links') && results.get('links').size > 0 && me && (isTop || showLinks)) {
const size = isTop ? Math.min(results.get('links').size, theLimit) : results.get('links').size;
const isMax = size === results.get('links').size
links = (
<PanelLayout
title='Links'
headerButtonTo={isMax ? undefined : '/search/links'}
headerButtonTitle={isMax ? undefined : 'See more'}
footerButtonTo={isMax ? undefined : '/search/links'}
footerButtonTitle={isMax ? undefined : 'See more'}
noPadding
>
<div className={[_s.d, _s.pb10, _s.px15, _s.mb15, _s.borderBottom1PX, _s.borderColorSecondary].join(' ')}>
<Text color='tertiary' size='small'>
Showing {size} of {results.get('links').size} results
</Text>
</div>
{
results.get('links').slice(0, size).map((linkId) => <PreviewCardItem id={linkId} />)
}
</PanelLayout>
)
}
if (results.get('hashtags') && results.get('hashtags').size > 0 && me && (isTop || showHashtags)) {
const size = isTop ? Math.min(results.get('hashtags').size, theLimit) : results.get('hashtags').size;
const isMax = size === results.get('hashtags').size
@ -188,9 +215,9 @@ class Search extends ImmutablePureComponent {
)
}
if (!accounts && !statuses && !hashtags && !groups) {
if (!accounts && !statuses && !hashtags && !groups && !links) {
return (
<ResponsiveClassesComponent classNamesXS={_s.px10}>
<ResponsiveClassesComponent classNamesXS={[_s.px10, _s.pt15].join(' ')}>
<Block>
<ColumnIndicator type='missing' message='No search results.' />
</Block>
@ -203,6 +230,7 @@ class Search extends ImmutablePureComponent {
{accounts}
{groups}
{statuses}
{links}
{hashtags}
</div>
)