search/related posts refinements
This commit is contained in:
parent
f915b2b8b3
commit
61a66127d1
@ -109,7 +109,7 @@ export function joinZapRankPersonalView (me, models) {
|
||||
// this grabs all the stuff we need to display the item list and only
|
||||
// hits the db once ... orderBy needs to be duplicated on the outer query because
|
||||
// joining does not preserve the order of the inner query
|
||||
async function itemQueryWithMeta ({ me, models, query, orderBy = '' }, ...args) {
|
||||
export async function itemQueryWithMeta ({ me, models, query, orderBy = '' }, ...args) {
|
||||
if (!me) {
|
||||
return await models.$queryRawUnsafe(`
|
||||
SELECT "Item".*, to_json(users.*) as user, to_jsonb("Sub".*) as sub
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { decodeCursor, LIMIT, nextCursorEncoded } from '../../lib/cursor'
|
||||
import { whenToFrom } from '../../lib/time'
|
||||
import { getItem } from './item'
|
||||
import { getItem, itemQueryWithMeta, SELECT } from './item'
|
||||
|
||||
function queryParts (q) {
|
||||
const regex = /"([^"]*)"/gm
|
||||
@ -58,7 +58,8 @@ export default {
|
||||
max_doc_freq: 5,
|
||||
min_word_length: 2,
|
||||
max_query_terms: 25,
|
||||
minimum_should_match: minMatch || '10%'
|
||||
minimum_should_match: minMatch || '10%',
|
||||
boost_terms: 100
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -94,7 +95,7 @@ export default {
|
||||
]
|
||||
}
|
||||
|
||||
let items = await search.search({
|
||||
const results = await search.search({
|
||||
index: process.env.OPENSEARCH_INDEX,
|
||||
size: limit,
|
||||
from: decodedCursor.offset,
|
||||
@ -141,9 +142,19 @@ export default {
|
||||
}
|
||||
})
|
||||
|
||||
items = items.body.hits.hits.map(async e => {
|
||||
// this is super inefficient but will suffice until we do something more generic
|
||||
return await getItem(parent, { id: e._source.id }, { me, models })
|
||||
const values = results.body.hits.hits.map((e, i) => {
|
||||
return `(${e._source.id}, ${i})`
|
||||
}).join(',')
|
||||
|
||||
const items = await itemQueryWithMeta({
|
||||
me,
|
||||
models,
|
||||
query: `
|
||||
WITH r(id, rank) AS (VALUES ${values})
|
||||
${SELECT}, rank
|
||||
FROM "Item"
|
||||
JOIN r ON "Item".id = r.id`,
|
||||
orderBy: 'ORDER BY rank ASC'
|
||||
})
|
||||
|
||||
return {
|
||||
@ -406,14 +417,23 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
// return highlights
|
||||
const items = sitems.body.hits.hits.map(async e => {
|
||||
// this is super inefficient but will suffice until we do something more generic
|
||||
const item = await getItem(parent, { id: e._source.id }, { me, models })
|
||||
const values = sitems.body.hits.hits.map((e, i) => {
|
||||
return `(${e._source.id}, ${i})`
|
||||
}).join(',')
|
||||
|
||||
const items = (await itemQueryWithMeta({
|
||||
me,
|
||||
models,
|
||||
query: `
|
||||
WITH r(id, rank) AS (VALUES ${values})
|
||||
${SELECT}, rank
|
||||
FROM "Item"
|
||||
JOIN r ON "Item".id = r.id`,
|
||||
orderBy: 'ORDER BY rank ASC'
|
||||
})).map((item, i) => {
|
||||
const e = sitems.body.hits.hits[i]
|
||||
item.searchTitle = (e.highlight?.title && e.highlight.title[0]) || item.title
|
||||
item.searchText = (e.highlight?.text && e.highlight.text.join(' ... ')) || undefined
|
||||
|
||||
return item
|
||||
})
|
||||
|
||||
|
@ -161,7 +161,7 @@ function TopLevelItem ({ item, noReply, ...props }) {
|
||||
{!noReply &&
|
||||
<>
|
||||
<Reply item={item} replyOpen placeholder={item.ncomments > 3 ? 'fractions of a penny for your thoughts?' : 'early comments get more zaps'} onCancelQuote={cancelQuote} onQuoteReply={quoteReply} quote={quote} />
|
||||
{!item.position && !item.isJob && !item.parentId && !item.bounty > 0 && <Related title={item.title} itemId={item.id} />}
|
||||
{!item.position && !item.isJob && !item.parentId && !(item.bounty > 0) && <Related title={item.title} itemId={item.id} show={item.ncomments < 3} />}
|
||||
{item.bounty > 0 && <PastBounties item={item} />}
|
||||
</>}
|
||||
</ItemComponent>
|
||||
|
@ -4,7 +4,7 @@
|
||||
max-width: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
padding-bottom: .15rem;
|
||||
margin-bottom: .15rem;
|
||||
}
|
||||
|
||||
.notification {
|
||||
@ -35,7 +35,7 @@ a.title:visited {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
flex: 1 0 128px;
|
||||
padding-bottom: .15rem;
|
||||
margin-bottom: .15rem;
|
||||
}
|
||||
|
||||
.newComment {
|
||||
@ -169,8 +169,10 @@ a.link:visited {
|
||||
background-color: var(--theme-grey);
|
||||
width: 500px;
|
||||
border-radius: .4rem;
|
||||
height: 17px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.skeleton .title::after {
|
||||
content: "\00a0";
|
||||
}
|
||||
|
||||
.skeleton .name {
|
||||
@ -181,12 +183,19 @@ a.link:visited {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.skeleton .hunk {
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.skeleton .link {
|
||||
height: 14px;
|
||||
background-color: var(--theme-grey);
|
||||
width: 800px;
|
||||
border-radius: .3rem;
|
||||
margin: 2px 0px;
|
||||
line-height: .8rem;
|
||||
}
|
||||
|
||||
.skeleton .link::after {
|
||||
content: "\00a0";
|
||||
}
|
||||
|
||||
.skeleton .otherItem {
|
||||
|
@ -28,7 +28,7 @@ export default function Items ({ ssrData, variables = {}, query, destructureData
|
||||
pins?.reduce((a, p) => { a[p.position] = p; return a }, {}), [pins])
|
||||
|
||||
const Skeleton = useCallback(() =>
|
||||
<ItemsSkeleton rank={rank} startRank={items?.length} limit={variables.limit} />, [rank, items])
|
||||
<ItemsSkeleton rank={rank} startRank={items?.length} limit={variables.limit} Footer={Foooter} />, [rank, items])
|
||||
|
||||
if (!dat) {
|
||||
return <Skeleton />
|
||||
@ -65,14 +65,17 @@ export function ListItem ({ item, ...props }) {
|
||||
)
|
||||
}
|
||||
|
||||
export function ItemsSkeleton ({ rank, startRank = 0, limit = LIMIT }) {
|
||||
export function ItemsSkeleton ({ rank, startRank = 0, limit = LIMIT, Footer }) {
|
||||
const items = new Array(limit).fill(null)
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.grid}>
|
||||
{items.map((_, i) => (
|
||||
<ItemSkeleton rank={rank && i + startRank + 1} key={i + startRank} />
|
||||
))}
|
||||
</div>
|
||||
<Footer invisible cursor />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ import Button from 'react-bootstrap/Button'
|
||||
import { useState } from 'react'
|
||||
import Link from 'next/link'
|
||||
|
||||
export default function MoreFooter ({ cursor, count, fetchMore, Skeleton, noMoreText = 'GENESIS' }) {
|
||||
export default function MoreFooter ({ cursor, count, fetchMore, Skeleton, invisible, noMoreText = 'GENESIS' }) {
|
||||
const [loading, setLoading] = useState(false)
|
||||
|
||||
if (loading) {
|
||||
@ -33,10 +33,10 @@ export default function MoreFooter ({ cursor, count, fetchMore, Skeleton, noMore
|
||||
)
|
||||
}
|
||||
|
||||
return <div className='d-flex justify-content-center mt-3 mb-1'><Footer /></div>
|
||||
return <div className={`d-flex justify-content-center mt-3 mb-1 ${invisible ? 'invisible' : ''}`}><Footer /></div>
|
||||
}
|
||||
|
||||
export function NavigateFooter ({ cursor, count, fetchMore, href, text, noMoreText = 'NO MORE' }) {
|
||||
export function NavigateFooter ({ cursor, count, fetchMore, href, text, invisible, noMoreText = 'NO MORE' }) {
|
||||
let Footer
|
||||
if (cursor) {
|
||||
Footer = () => (
|
||||
@ -48,5 +48,5 @@ export function NavigateFooter ({ cursor, count, fetchMore, href, text, noMoreTe
|
||||
)
|
||||
}
|
||||
|
||||
return <div className='d-flex justify-content-start my-1'><Footer /></div>
|
||||
return <div className={`d-flex justify-content-start my-1 ${invisible ? 'invisible' : ''}`}><Footer /></div>
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import { NavigateFooter } from './more-footer'
|
||||
|
||||
const LIMIT = 5
|
||||
|
||||
export default function Related ({ title, itemId }) {
|
||||
export default function Related ({ title, itemId, ...props }) {
|
||||
const variables = { title, id: itemId, limit: LIMIT }
|
||||
return (
|
||||
<AccordianItem
|
||||
@ -18,6 +18,7 @@ export default function Related ({ title, itemId }) {
|
||||
Footer={props => <NavigateFooter {...props} href={`/items/${itemId}/related`} text='view all related items' />}
|
||||
/>
|
||||
}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user