search highlighting
This commit is contained in:
parent
075d147f63
commit
66d2c4f9a9
|
@ -327,8 +327,8 @@ export default {
|
||||||
},
|
},
|
||||||
highlight: {
|
highlight: {
|
||||||
fields: {
|
fields: {
|
||||||
title: { number_of_fragments: 0, pre_tags: ['***'], post_tags: ['***'] },
|
title: { number_of_fragments: 0, pre_tags: [':high['], post_tags: [']'] },
|
||||||
text: { number_of_fragments: 0, pre_tags: ['***'], post_tags: ['***'] }
|
text: { number_of_fragments: 0, pre_tags: [':high['], post_tags: [']'] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,12 +344,10 @@ export default {
|
||||||
// return highlights
|
// return highlights
|
||||||
const items = sitems.body.hits.hits.map(e => {
|
const items = sitems.body.hits.hits.map(e => {
|
||||||
const item = e._source
|
const item = e._source
|
||||||
if (e.highlight?.title) {
|
|
||||||
item.title = e.highlight.title[0]
|
item.searchTitle = (e.highlight.title && e.highlight.title[0]) || item.title
|
||||||
}
|
item.searchText = (e.highlight.text && e.highlight.text[0]) || item.text
|
||||||
if (e.highlight?.text) {
|
|
||||||
item.text = e.highlight.text[0]
|
|
||||||
}
|
|
||||||
return item
|
return item
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,9 @@ export default gql`
|
||||||
createdAt: String!
|
createdAt: String!
|
||||||
updatedAt: String!
|
updatedAt: String!
|
||||||
title: String
|
title: String
|
||||||
|
searchTitle: String
|
||||||
url: String
|
url: String
|
||||||
|
searchText: String
|
||||||
text: String
|
text: String
|
||||||
parentId: Int
|
parentId: Int
|
||||||
parent: Item
|
parent: Item
|
||||||
|
|
|
@ -165,7 +165,7 @@ export default function Comment ({
|
||||||
: (
|
: (
|
||||||
<div className={styles.text}>
|
<div className={styles.text}>
|
||||||
<Text nofollow={item.sats + item.boost < NOFOLLOW_LIMIT}>
|
<Text nofollow={item.sats + item.boost < NOFOLLOW_LIMIT}>
|
||||||
{truncate ? truncateString(item.text) : item.text}
|
{truncate ? truncateString(item.text) : item.searchText || item.text}
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -42,9 +42,9 @@ function ItemEmbed ({ item }) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
function TopLevelItem ({ item, noReply }) {
|
function TopLevelItem ({ item, noReply, ...props }) {
|
||||||
return (
|
return (
|
||||||
<Item item={item}>
|
<Item item={item} {...props}>
|
||||||
{item.text && <ItemText item={item} />}
|
{item.text && <ItemText item={item} />}
|
||||||
{item.url && <ItemEmbed item={item} />}
|
{item.url && <ItemEmbed item={item} />}
|
||||||
{!noReply && <Reply parentId={item.id} replyOpen />}
|
{!noReply && <Reply parentId={item.id} replyOpen />}
|
||||||
|
@ -53,7 +53,7 @@ function TopLevelItem ({ item, noReply }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ItemText ({ item }) {
|
function ItemText ({ item }) {
|
||||||
return <Text nofollow={item.sats + item.boost < NOFOLLOW_LIMIT}>{item.text}</Text>
|
return <Text nofollow={item.sats + item.boost < NOFOLLOW_LIMIT}>{item.searchText || item.text}</Text>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ItemFull ({ item, bio, ...props }) {
|
export default function ItemFull ({ item, bio, ...props }) {
|
||||||
|
|
|
@ -6,6 +6,13 @@ import { useEffect, useRef, useState } from 'react'
|
||||||
import Countdown from './countdown'
|
import Countdown from './countdown'
|
||||||
import { NOFOLLOW_LIMIT } from '../lib/constants'
|
import { NOFOLLOW_LIMIT } from '../lib/constants'
|
||||||
import Pin from '../svgs/pushpin-fill.svg'
|
import Pin from '../svgs/pushpin-fill.svg'
|
||||||
|
import reactStringReplace from 'react-string-replace'
|
||||||
|
|
||||||
|
function SearchTitle ({ title }) {
|
||||||
|
return reactStringReplace(title, /:high\[(.+)\]/g, (match, i) => {
|
||||||
|
return <mark key={`mark-${match}`}>{match}</mark>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export default function Item ({ item, rank, children }) {
|
export default function Item ({ item, rank, children }) {
|
||||||
const mine = item.mine
|
const mine = item.mine
|
||||||
|
@ -34,7 +41,9 @@ export default function Item ({ item, rank, children }) {
|
||||||
<div className={styles.hunk}>
|
<div className={styles.hunk}>
|
||||||
<div className={`${styles.main} flex-wrap ${wrap ? 'd-inline' : ''}`}>
|
<div className={`${styles.main} flex-wrap ${wrap ? 'd-inline' : ''}`}>
|
||||||
<Link href={`/items/${item.id}`} passHref>
|
<Link href={`/items/${item.id}`} passHref>
|
||||||
<a ref={titleRef} className={`${styles.title} text-reset mr-2`}>{item.title}</a>
|
<a ref={titleRef} className={`${styles.title} text-reset mr-2`}>
|
||||||
|
{item.searchTitle ? <SearchTitle title={item.searchTitle} /> : item.title}
|
||||||
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
{item.url &&
|
{item.url &&
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -5,6 +5,25 @@ import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
|
||||||
/* Use `…/dist/cjs/…` if you’re not in ESM! */
|
/* Use `…/dist/cjs/…` if you’re not in ESM! */
|
||||||
import { atomDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'
|
import { atomDark } from 'react-syntax-highlighter/dist/cjs/styles/prism'
|
||||||
import mention from '../lib/remark-mention'
|
import mention from '../lib/remark-mention'
|
||||||
|
import remarkDirective from 'remark-directive'
|
||||||
|
import { visit } from 'unist-util-visit'
|
||||||
|
|
||||||
|
function myRemarkPlugin () {
|
||||||
|
return (tree) => {
|
||||||
|
visit(tree, (node) => {
|
||||||
|
if (
|
||||||
|
node.type === 'textDirective' ||
|
||||||
|
node.type === 'leafDirective'
|
||||||
|
) {
|
||||||
|
if (node.name !== 'high') return
|
||||||
|
|
||||||
|
const data = node.data || (node.data = {})
|
||||||
|
data.hName = 'mark'
|
||||||
|
data.hProperties = {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default function Text ({ nofollow, children }) {
|
export default function Text ({ nofollow, children }) {
|
||||||
return (
|
return (
|
||||||
|
@ -37,7 +56,7 @@ export default function Text ({ nofollow, children }) {
|
||||||
},
|
},
|
||||||
a: ({ node, ...props }) => <a target='_blank' rel={nofollow ? 'nofollow' : null} {...props} />
|
a: ({ node, ...props }) => <a target='_blank' rel={nofollow ? 'nofollow' : null} {...props} />
|
||||||
}}
|
}}
|
||||||
remarkPlugins={[gfm, mention]}
|
remarkPlugins={[gfm, mention, remarkDirective, myRemarkPlugin]}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
|
|
|
@ -98,6 +98,8 @@ export const ITEM_SEARCH = gql`
|
||||||
items {
|
items {
|
||||||
...ItemFields
|
...ItemFields
|
||||||
text
|
text
|
||||||
|
searchTitle
|
||||||
|
searchText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -42,14 +42,17 @@
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-longpressable": "^1.1.1",
|
"react-longpressable": "^1.1.1",
|
||||||
"react-markdown": "^6.0.2",
|
"react-markdown": "^6.0.2",
|
||||||
|
"react-string-replace": "^0.4.4",
|
||||||
"react-syntax-highlighter": "^15.4.3",
|
"react-syntax-highlighter": "^15.4.3",
|
||||||
"react-textarea-autosize": "^8.3.3",
|
"react-textarea-autosize": "^8.3.3",
|
||||||
"react-tweet-embed": "^1.3.1",
|
"react-tweet-embed": "^1.3.1",
|
||||||
|
"remark-directive": "^2.0.1",
|
||||||
"remark-gfm": "^1.0.0",
|
"remark-gfm": "^1.0.0",
|
||||||
"remove-markdown": "^0.3.0",
|
"remove-markdown": "^0.3.0",
|
||||||
"sass": "^1.32.8",
|
"sass": "^1.32.8",
|
||||||
"secp256k1": "^4.0.2",
|
"secp256k1": "^4.0.2",
|
||||||
"swr": "^0.5.4",
|
"swr": "^0.5.4",
|
||||||
|
"unist-util-visit": "^4.1.0",
|
||||||
"use-dark-mode": "^2.3.1",
|
"use-dark-mode": "^2.3.1",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"webln": "^0.2.2",
|
"webln": "^0.2.2",
|
||||||
|
|
|
@ -65,6 +65,11 @@ $tooltip-bg: #5c8001;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mark {
|
||||||
|
background-color: var(--primary);
|
||||||
|
padding: 0 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
.table-sm th, .table-sm td {
|
.table-sm th, .table-sm td {
|
||||||
line-height: 1.2rem;
|
line-height: 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue