Browse Source

标记搜索关键词

pull/16/head
hole-thu 3 years ago
parent
commit
88677e9b40
  1. 61
      src/Common.js
  2. 77
      src/Flows.js

61
src/Common.js

@ -68,52 +68,7 @@ function normalize_url(url) {
return /^https?:\/\//.test(url) ? url : 'http://' + url;
}
/*
export class HighlightedText extends PureComponent {
render() {
return (
<pre>
{this.props.parts.map((part, idx) => {
let [rule, p] = part;
return (
<span key={idx}>
{rule === 'url_pid' ? (
<span className="url-pid-link" title={p}>
/##
</span>
) : rule === 'url' ? (
<a href={normalize_url(p)} target="_blank" rel="noopener">
{p}
</a>
) : rule === 'pid' ? (
<a
href={'#' + p}
onClick={(e) => {
e.preventDefault();
this.props.show_pid(p.substring(1));
}}
>
{p}
</a>
) : rule === 'nickname' ? (
<ColoredSpan colors={this.props.color_picker.get(p)}>
{p}
</ColoredSpan>
) : rule === 'search' ? (
<span className="search-query-highlight">{p}</span>
) : (
p
)}
</span>
);
})}
</pre>
);
}
}
*/
// props: text, show_pid, color_picker
// props: text, show_pid, color_picker, search_param
export class HighlightedMarkdown extends Component {
render() {
const props = this.props;
@ -169,13 +124,21 @@ export class HighlightedMarkdown extends Component {
},
processNode(node, children, index) {
const originalText = node.data;
const splitted = split_text(originalText, [
let rules = [
['url_pid', URL_PID_RE],
['url', URL_RE],
['pid', PID_RE],
['nickname', NICKNAME_RE],
['tag', TAG_RE],
]);
['tag', TAG_RE]
];
if (props.search_param) {
let search_kws = props.search_param.split(' ').filter(s => !!s);
rules.push([
'search',
new RegExp(`(${search_kws.map((s) => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join("|")})`, "g")
]);
}
const splitted = split_text(originalText, rules);
return (
<React.Fragment key={index}>

77
src/Flows.js

@ -98,7 +98,7 @@ class Reply extends PureComponent {
render() {
const {
info, color_picker, show_pid, do_filter_name, do_delete,
do_report, do_block
do_report, do_block, search_param
} = this.props;
const author = info.name,
replyText = info.text;
@ -173,6 +173,7 @@ class Reply extends PureComponent {
text={replyText}
color_picker={color_picker}
show_pid={show_pid}
search_param={search_param}
/>
</div>
</div>
@ -227,7 +228,7 @@ class FlowItem extends PureComponent {
const {
info, is_quote, cached, attention, can_del, do_filter_name, do_delete,
do_edit_cw, do_edit_score, timestamp, img_clickable, color_picker,
show_pid, do_vote, do_block
show_pid, do_vote, do_block, search_param
} = this.props;
const { cw, hot_score } = this.state;
return (
@ -358,39 +359,8 @@ class FlowItem extends PureComponent {
text={info.text}
color_picker={color_picker}
show_pid={show_pid}
search_param={search_param}
/>
{info.type === 'image' && (
<p className="img">
{img_clickable ? (
<a
className="no-underline"
href={IMAGE_BASE + info.url}
target="_blank"
>
<img
src={IMAGE_BASE + info.url}
onError={(e) => {
if (e.target.src === IMAGE_BASE + info.url) {
e.target.src = IMAGE_BAK_BASE + info.url;
}
}}
alt={IMAGE_BASE + info.url}
/>
</a>
) : (
<img
src={IMAGE_BASE + info.url}
onError={(e) => {
if (e.target.src === IMAGE_BASE + info.url) {
e.target.src = IMAGE_BAK_BASE + info.url;
}
}}
alt={IMAGE_BASE + info.url}
/>
)}
</p>
)}
{/*{info.type==='audio' && <AudioWidget src={AUDIO_BASE+info.url} />}*/}
</div>
{ info.poll && (
<div className={!do_vote ? "box-poll disabled" : "box-poll"}>
@ -726,6 +696,7 @@ class FlowSidebar extends PureComponent {
img_clickable={true}
color_picker={this.color_picker}
show_pid={show_pid}
search_param={this.props.search_param}
replies={this.state.replies}
set_variant={(variant) => {
this.set_variant(null, variant);
@ -846,6 +817,7 @@ class FlowSidebar extends PureComponent {
info={reply}
color_picker={this.color_picker}
show_pid={show_pid}
search_param={this.props.search_param}
set_variant={(variant) => {
this.set_variant(reply.cid, variant);
}}
@ -967,6 +939,7 @@ class FlowItemRow extends PureComponent {
<FlowSidebar
key={+new Date()}
info={this.state.info}
search_param={this.props.search_param}
replies={this.state.replies}
attention={this.state.attention}
sync_state={this.setState.bind(this)}
@ -979,50 +952,41 @@ class FlowItemRow extends PureComponent {
}
render() {
let show_pid = load_single_meta(this.props.show_sidebar, this.props.token, [
const {show_sidebar, token, search_param, is_quote } = this.props;
let show_pid = load_single_meta(show_sidebar, token, [
this.state.info.pid,
]);
let hl_rules = [
['url_pid', URL_PID_RE],
['url', URL_RE],
['pid', PID_RE],
['nickname', NICKNAME_RE],
['tag', TAG_RE],
];
if (this.props.search_param) {
hl_rules.push([
'search',
!!this.props.search_param.match(/\/.+\//)
? build_highlight_re(this.props.search_param, ' ', 'gi', true) // Use regex
: build_highlight_re(this.props.search_param, ' ', 'gi'), // Don't use regex
]);
}
let parts = split_text(this.state.info.text, hl_rules);
//console.log('hl:', parts,this.state.info.pid);
let quote_id = null;
if (!this.props.is_quote)
if (!is_quote)
for (let [mode, content] of parts) {
content = content.length > 0 ? content.substring(1) : content;
if (
mode === 'pid' &&
QUOTE_BLACKLIST.indexOf(content) === -1 &&
parseInt(content) < parseInt(this.state.info.pid)
)
if (quote_id === null) quote_id = parseInt(content);
else {
quote_id = null;
break;
}
) {
if (quote_id === null)
quote_id = parseInt(content);
else {
quote_id = null;
break;
}
}
}
let res = (
<div
className={
'flow-item-row flow-item-row-with-prompt' +
(this.props.is_quote ? ' flow-item-row-quote' : '')
(is_quote ? ' flow-item-row-quote' : '')
}
onClick={(event) => {
if (!CLICKABLE_TAGS[event.target.tagName.toLowerCase()])
@ -1030,7 +994,6 @@ class FlowItemRow extends PureComponent {
}}
>
<FlowItem
parts={parts}
info={this.state.info}
attention={this.state.attention}
img_clickable={false}
@ -1039,6 +1002,7 @@ class FlowItemRow extends PureComponent {
show_pid={show_pid}
replies={this.state.replies}
cached={this.state.cached}
search_param={search_param}
/>
<div className="flow-reply-row">
{this.state.reply_status === 'loading' && (
@ -1064,6 +1028,7 @@ class FlowItemRow extends PureComponent {
info={reply}
color_picker={this.color_picker}
show_pid={show_pid}
search_param={search_param}
/>
))}
{this.state.replies.length > PREVIEW_REPLY_COUNT && (

Loading…
Cancel
Save