Added links/PreviewCardItem to Search feature results
• Added: - links/PreviewCardItem to Search feature results
This commit is contained in:
parent
7887bc21bc
commit
68fe383a28
107
app/javascript/gabsocial/components/preview_card_item.js
Normal file
107
app/javascript/gabsocial/components/preview_card_item.js
Normal file
@ -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>
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user