formatting
This commit is contained in:
585
src/Flows.js
585
src/Flows.js
@@ -23,7 +23,7 @@ import LazyLoad, { forceCheck } from './react-lazyload/src';
|
||||
import { TokenCtx, ReplyForm } from './UserAction';
|
||||
import { API, parse_replies } from './flows_api';
|
||||
import { cache } from './cache';
|
||||
import { save_attentions } from './Attention'
|
||||
import { save_attentions } from './Attention';
|
||||
import Poll from 'react-polls';
|
||||
|
||||
/*
|
||||
@@ -97,8 +97,14 @@ class Reply extends PureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
info, color_picker, show_pid, do_filter_name, do_delete,
|
||||
do_report, do_block, search_param
|
||||
info,
|
||||
color_picker,
|
||||
show_pid,
|
||||
do_filter_name,
|
||||
do_delete,
|
||||
do_report,
|
||||
do_block,
|
||||
search_param,
|
||||
} = this.props;
|
||||
const author = info.name,
|
||||
replyText = info.text;
|
||||
@@ -126,9 +132,7 @@ class Reply extends PureComponent {
|
||||
</span>
|
||||
)}
|
||||
|
||||
{(
|
||||
<span className="box-header-name">{info.name}</span>
|
||||
)}
|
||||
{<span className="box-header-name">{info.name}</span>}
|
||||
{info.author_title && (
|
||||
<span className="box-header-name author-title">{`"${info.author_title}"`}</span>
|
||||
)}
|
||||
@@ -138,21 +142,21 @@ class Reply extends PureComponent {
|
||||
onClick={() => {
|
||||
do_delete('cid', info.cid);
|
||||
}}
|
||||
> 🗑️ </span>
|
||||
>
|
||||
{' '}
|
||||
🗑️{' '}
|
||||
</span>
|
||||
)}
|
||||
{!!do_block && (
|
||||
<span
|
||||
className="clickable"
|
||||
onClick={do_block}
|
||||
> 🚫 </span>
|
||||
<span className="clickable" onClick={do_block}>
|
||||
{' '}
|
||||
🚫{' '}
|
||||
</span>
|
||||
)}
|
||||
{!!do_report && (
|
||||
<>
|
||||
|
||||
<span
|
||||
className="clickable"
|
||||
onClick={do_report}
|
||||
>
|
||||
<span className="clickable" onClick={do_report}>
|
||||
<span className="icon icon-flag" />
|
||||
</span>
|
||||
|
||||
@@ -219,9 +223,21 @@ class FlowItem extends PureComponent {
|
||||
|
||||
render() {
|
||||
const {
|
||||
info, is_quote, cached, attention, can_del, do_filter_name, do_delete,
|
||||
do_edit_cw, timestamp, img_clickable, color_picker,
|
||||
show_pid, do_vote, do_block, search_param
|
||||
info,
|
||||
is_quote,
|
||||
cached,
|
||||
attention,
|
||||
can_del,
|
||||
do_filter_name,
|
||||
do_delete,
|
||||
do_edit_cw,
|
||||
timestamp,
|
||||
img_clickable,
|
||||
color_picker,
|
||||
show_pid,
|
||||
do_vote,
|
||||
do_block,
|
||||
search_param,
|
||||
} = this.props;
|
||||
const { cw } = this.state;
|
||||
return (
|
||||
@@ -241,9 +257,7 @@ class FlowItem extends PureComponent {
|
||||
parseInt(info.pid, 10) > window.LATEST_POST_ID && (
|
||||
<div className="flow-item-dot" />
|
||||
)}
|
||||
{!!attention && !cached && (
|
||||
<div className="flow-item-dot" />
|
||||
)}
|
||||
{!!attention && !cached && <div className="flow-item-dot" />}
|
||||
<div className="box-header">
|
||||
{!!do_filter_name && (
|
||||
<span
|
||||
@@ -259,9 +273,7 @@ class FlowItem extends PureComponent {
|
||||
<span className="box-header-badge">
|
||||
{info.likenum}
|
||||
<span
|
||||
className={
|
||||
'icon icon-' + (attention ? 'star-ok' : 'star')
|
||||
}
|
||||
className={'icon icon-' + (attention ? 'star-ok' : 'star')}
|
||||
/>
|
||||
</span>
|
||||
)}
|
||||
@@ -272,10 +284,7 @@ class FlowItem extends PureComponent {
|
||||
</span>
|
||||
)}
|
||||
<code className="box-id">
|
||||
<a
|
||||
href={'##' + info.pid}
|
||||
onClick={this.copy_link.bind(this)}
|
||||
>
|
||||
<a href={'##' + info.pid} onClick={this.copy_link.bind(this)}>
|
||||
#{info.pid}
|
||||
</a>
|
||||
</code>
|
||||
@@ -283,22 +292,23 @@ class FlowItem extends PureComponent {
|
||||
{info.author_title && (
|
||||
<span className="box-header-name author-title">{`"${info.author_title}"`}</span>
|
||||
)}
|
||||
{info.is_reported && (
|
||||
<span className="danger-info"> R </span>
|
||||
)}
|
||||
{info.is_reported && <span className="danger-info"> R </span>}
|
||||
{!!do_delete && !!info.can_del && (
|
||||
<span
|
||||
className="clickable"
|
||||
onClick={() => {
|
||||
do_delete('pid', info.pid);
|
||||
}}
|
||||
> 🗑️ </span>
|
||||
>
|
||||
{' '}
|
||||
🗑️{' '}
|
||||
</span>
|
||||
)}
|
||||
{!!do_block && (
|
||||
<span
|
||||
className="clickable"
|
||||
onClick={do_block}
|
||||
> 🚫 </span>
|
||||
<span className="clickable" onClick={do_block}>
|
||||
{' '}
|
||||
🚫{' '}
|
||||
</span>
|
||||
)}
|
||||
{info.dangerous_user && (
|
||||
<span className="danger-info"> {info.dangerous_user} </span>
|
||||
@@ -306,30 +316,24 @@ class FlowItem extends PureComponent {
|
||||
{info.blocked_count && (
|
||||
<span className="danger-info"> {info.blocked_count} </span>
|
||||
)}
|
||||
{info.cw !== null &&
|
||||
(!do_edit_cw || !info.can_del) && (
|
||||
<span className="box-header-cw">{info.cw}</span>
|
||||
{info.cw !== null && (!do_edit_cw || !info.can_del) && (
|
||||
<span className="box-header-cw">{info.cw}</span>
|
||||
)}
|
||||
{
|
||||
!!do_edit_cw && !!info.can_del && (
|
||||
<div className="box-header-cw-edit clickable">
|
||||
<input
|
||||
type="text"
|
||||
value={cw}
|
||||
maxLength="32"
|
||||
placeholder="编辑折叠警告"
|
||||
onChange={this.on_cw_change.bind(this)}
|
||||
/>
|
||||
<button type="button"
|
||||
onClick={(e)=>do_edit_cw(cw, info.pid)}>
|
||||
更新
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
info.allow_search && <span> 📢 </span>
|
||||
}
|
||||
{!!do_edit_cw && !!info.can_del && (
|
||||
<div className="box-header-cw-edit clickable">
|
||||
<input
|
||||
type="text"
|
||||
value={cw}
|
||||
maxLength="32"
|
||||
placeholder="编辑折叠警告"
|
||||
onChange={this.on_cw_change.bind(this)}
|
||||
/>
|
||||
<button type="button" onClick={(e) => do_edit_cw(cw, info.pid)}>
|
||||
更新
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
{info.allow_search && <span> 📢 </span>}
|
||||
<Time stamp={info.timestamp} short={!img_clickable} />
|
||||
</div>
|
||||
{!!info.hot_score && (
|
||||
@@ -343,14 +347,14 @@ class FlowItem extends PureComponent {
|
||||
search_param={search_param}
|
||||
/>
|
||||
</div>
|
||||
{ info.poll && (
|
||||
<div className={!do_vote ? "box-poll disabled" : "box-poll"}>
|
||||
{info.poll && (
|
||||
<div className={!do_vote ? 'box-poll disabled' : 'box-poll'}>
|
||||
<Poll
|
||||
key={info.poll.vote || 'x'}
|
||||
question={""}
|
||||
question={''}
|
||||
answers={info.poll.answers}
|
||||
onVote={do_vote || (() => {})}
|
||||
customStyles={{'theme': 'cyan'}}
|
||||
customStyles={{ theme: 'cyan' }}
|
||||
noStorage={true}
|
||||
vote={localStorage['VOTE_RECORD:' + info.pid] || info.poll.vote}
|
||||
/>
|
||||
@@ -358,8 +362,7 @@ class FlowItem extends PureComponent {
|
||||
)}
|
||||
{!!(attention && info.variant.latest_reply) && (
|
||||
<p className="box-footer">
|
||||
最新回复{' '}
|
||||
<Time stamp={info.variant.latest_reply} short={false} />
|
||||
最新回复 <Time stamp={info.variant.latest_reply} short={false} />
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
@@ -432,7 +435,7 @@ class FlowSidebar extends PureComponent {
|
||||
info: update_count
|
||||
? Object.assign({}, prev.info, {
|
||||
reply: '' + json.data.length,
|
||||
likenum: ''+json.likenum,
|
||||
likenum: '' + json.likenum,
|
||||
})
|
||||
: prev.info,
|
||||
attention: !!json.attention,
|
||||
@@ -473,16 +476,16 @@ class FlowSidebar extends PureComponent {
|
||||
this.setState({
|
||||
attention: json.attention,
|
||||
info: Object.assign({}, prev_info, {
|
||||
likenum: ''+json.likenum,
|
||||
}),
|
||||
likenum: '' + json.likenum,
|
||||
}),
|
||||
});
|
||||
|
||||
let saved_attentions = window.saved_attentions;
|
||||
if (json.attention && !saved_attentions.includes(pid)) {
|
||||
saved_attentions.unshift(pid)
|
||||
saved_attentions.unshift(pid);
|
||||
} else if (!json.attention && saved_attentions.includes(pid)) {
|
||||
const idx = saved_attentions.indexOf(pid);
|
||||
saved_attentions.splice(idx, 1)
|
||||
saved_attentions.splice(idx, 1);
|
||||
}
|
||||
window.saved_attentions = saved_attentions;
|
||||
save_attentions();
|
||||
@@ -490,8 +493,8 @@ class FlowSidebar extends PureComponent {
|
||||
this.syncState({
|
||||
attention: json.attention,
|
||||
info: Object.assign({}, prev_info, {
|
||||
likenum: ''+json.likenum,
|
||||
}),
|
||||
likenum: '' + json.likenum,
|
||||
}),
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
@@ -551,15 +554,15 @@ class FlowSidebar extends PureComponent {
|
||||
block(name, type, id, on_complete) {
|
||||
if (confirm(`确定拉黑${name}吗?后续将不会收到其发布的任何内容`)) {
|
||||
API.block(type, id, this.props.token)
|
||||
.then((json) => {
|
||||
let data = json.data;
|
||||
alert(`操作成功,其成为危险用户进度 ${data.curr}/${data.threshold}`)
|
||||
!!on_complete && on_complete();
|
||||
})
|
||||
.catch((e) => {
|
||||
alert('拉黑失败\n' + e);
|
||||
console.error(e)
|
||||
});
|
||||
.then((json) => {
|
||||
let data = json.data;
|
||||
alert(`操作成功,其成为危险用户进度 ${data.curr}/${data.threshold}`);
|
||||
!!on_complete && on_complete();
|
||||
})
|
||||
.catch((e) => {
|
||||
alert('拉黑失败\n' + e);
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -590,7 +593,7 @@ class FlowSidebar extends PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
make_do_delete(token, on_complete=null) {
|
||||
make_do_delete(token, on_complete = null) {
|
||||
const do_delete = (type, id) => {
|
||||
let note = prompt(`将删除${type}=${id}, 备注:`, '(无)');
|
||||
if (note !== null) {
|
||||
@@ -604,27 +607,29 @@ class FlowSidebar extends PureComponent {
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
return do_delete;
|
||||
}
|
||||
|
||||
do_edit_cw(cw, id) {
|
||||
API.update_cw(cw, id, this.props.token)
|
||||
.then((json) => {
|
||||
this.setState({
|
||||
info: Object.assign({}, this.state.info, { cw: cw }),
|
||||
API.update_cw(cw, id, this.props.token)
|
||||
.then((json) => {
|
||||
this.setState(
|
||||
{
|
||||
info: Object.assign({}, this.state.info, { cw: cw }),
|
||||
},
|
||||
() => {
|
||||
this.syncState({
|
||||
info: this.state.info,
|
||||
});
|
||||
});
|
||||
alert('已更新');
|
||||
})
|
||||
.catch((e) => {
|
||||
alert('更新失败\n' + e);
|
||||
console.error(e);
|
||||
});
|
||||
},
|
||||
);
|
||||
alert('已更新');
|
||||
})
|
||||
.catch((e) => {
|
||||
alert('更新失败\n' + e);
|
||||
console.error(e);
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -671,12 +676,16 @@ class FlowSidebar extends PureComponent {
|
||||
do_filter_name={
|
||||
replies_cnt[DZ_NAME] > 1 ? this.set_filter_name.bind(this) : null
|
||||
}
|
||||
do_delete={this.make_do_delete(this.props.token, ()=>{window.location.reload();})}
|
||||
do_delete={this.make_do_delete(this.props.token, () => {
|
||||
window.location.reload();
|
||||
})}
|
||||
do_edit_cw={this.do_edit_cw.bind(this)}
|
||||
do_vote={this.do_vote.bind(this)}
|
||||
do_block={() => {this.block(
|
||||
'洞主', 'post', this.state.info.pid, () => {window.location.reload();}
|
||||
)}}
|
||||
do_block={() => {
|
||||
this.block('洞主', 'post', this.state.info.pid, () => {
|
||||
window.location.reload();
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</ClickHandler>
|
||||
);
|
||||
@@ -766,41 +775,57 @@ class FlowSidebar extends PureComponent {
|
||||
条回复被删除
|
||||
</div>
|
||||
)}
|
||||
{replies_to_show.map((reply, i) => !reply.blocked && (
|
||||
<LazyLoad
|
||||
key={i}
|
||||
offset={1500}
|
||||
height="5em"
|
||||
overflow={true}
|
||||
once={true}
|
||||
>
|
||||
<ClickHandler
|
||||
callback={(e) => {
|
||||
this.show_reply_bar(reply.name, e);
|
||||
}}
|
||||
>
|
||||
<Reply
|
||||
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);
|
||||
}}
|
||||
do_filter_name={
|
||||
replies_cnt[reply.name] > 1
|
||||
? this.set_filter_name.bind(this)
|
||||
: null
|
||||
}
|
||||
do_delete={this.make_do_delete(this.props.token, this.load_replies.bind(this))}
|
||||
do_block={() => {this.block(
|
||||
reply.name, 'comment', reply.cid, this.load_replies.bind(this)
|
||||
)}}
|
||||
do_report={(e) => {this.report(e, `评论区${reply.name},评论id ${reply.cid}`)}}
|
||||
/>
|
||||
</ClickHandler>
|
||||
</LazyLoad>
|
||||
))}
|
||||
{replies_to_show.map(
|
||||
(reply, i) =>
|
||||
!reply.blocked && (
|
||||
<LazyLoad
|
||||
key={i}
|
||||
offset={1500}
|
||||
height="5em"
|
||||
overflow={true}
|
||||
once={true}
|
||||
>
|
||||
<ClickHandler
|
||||
callback={(e) => {
|
||||
this.show_reply_bar(reply.name, e);
|
||||
}}
|
||||
>
|
||||
<Reply
|
||||
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);
|
||||
}}
|
||||
do_filter_name={
|
||||
replies_cnt[reply.name] > 1
|
||||
? this.set_filter_name.bind(this)
|
||||
: null
|
||||
}
|
||||
do_delete={this.make_do_delete(
|
||||
this.props.token,
|
||||
this.load_replies.bind(this),
|
||||
)}
|
||||
do_block={() => {
|
||||
this.block(
|
||||
reply.name,
|
||||
'comment',
|
||||
reply.cid,
|
||||
this.load_replies.bind(this),
|
||||
);
|
||||
}}
|
||||
do_report={(e) => {
|
||||
this.report(
|
||||
e,
|
||||
`评论区${reply.name},评论id ${reply.cid}`,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</ClickHandler>
|
||||
</LazyLoad>
|
||||
),
|
||||
)}
|
||||
{this.state.rev && main_thread_elem}
|
||||
{this.props.token ? (
|
||||
<ReplyForm
|
||||
@@ -820,19 +845,27 @@ class FlowSidebar extends PureComponent {
|
||||
class FlowItemRow extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.needFold = props.info.cw &&
|
||||
this.needFold =
|
||||
props.info.cw &&
|
||||
!props.search_param &&
|
||||
(window.config.whitelist_cw.indexOf('*')==-1 && window.config.whitelist_cw.indexOf(props.info.cw)==-1) &&
|
||||
props.mode !== 'attention' && props.mode !== 'attention_finished';
|
||||
window.config.whitelist_cw.indexOf('*') == -1 &&
|
||||
window.config.whitelist_cw.indexOf(props.info.cw) == -1 &&
|
||||
props.mode !== 'attention' &&
|
||||
props.mode !== 'attention_finished';
|
||||
this.color_picker = new ColorPicker();
|
||||
this.state = {
|
||||
replies: props.info.comments ? parse_replies(props.info.comments, this.color_picker) : [],
|
||||
replies: props.info.comments
|
||||
? parse_replies(props.info.comments, this.color_picker)
|
||||
: [],
|
||||
reply_status: 'done',
|
||||
reply_error: null,
|
||||
info: Object.assign({}, props.info, { variant: {} }),
|
||||
hidden: window.config.block_words_v2.some((word) =>
|
||||
hidden:
|
||||
(window.config.block_words_v2.some((word) =>
|
||||
props.info.text.includes(word),
|
||||
) && !props.info.can_del || this.needFold,
|
||||
) &&
|
||||
!props.info.can_del) ||
|
||||
this.needFold,
|
||||
attention: props.info.attention,
|
||||
cached: true, // default no display anything
|
||||
};
|
||||
@@ -841,7 +874,7 @@ class FlowItemRow extends PureComponent {
|
||||
componentDidMount() {
|
||||
// cache from getlist, so always to this to update attention
|
||||
if (!this.props.info.comments) {
|
||||
//if (true || parseInt(this.state.info.reply, 10)) {
|
||||
//if (true || parseInt(this.state.info.reply, 10)) {
|
||||
this.load_replies(null, /*update_count=*/ false);
|
||||
}
|
||||
}
|
||||
@@ -918,14 +951,10 @@ class FlowItemRow extends PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const {show_sidebar, token, search_param, is_quote } = this.props;
|
||||
let show_pid = load_single_meta(show_sidebar, token, [
|
||||
this.state.info.pid,
|
||||
]);
|
||||
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 = [
|
||||
['pid', PID_RE],
|
||||
];
|
||||
let hl_rules = [['pid', PID_RE]];
|
||||
let parts = split_text(this.state.info.text, hl_rules);
|
||||
|
||||
//console.log('hl:', parts,this.state.info.pid);
|
||||
@@ -939,12 +968,11 @@ class FlowItemRow extends PureComponent {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -988,15 +1016,20 @@ class FlowItemRow extends PureComponent {
|
||||
<p>{this.state.reply_error}</p>
|
||||
</div>
|
||||
)}
|
||||
{this.state.replies.slice(0, PREVIEW_REPLY_COUNT).map((reply) => !reply.blocked && (
|
||||
<Reply
|
||||
key={reply.cid}
|
||||
info={reply}
|
||||
color_picker={this.color_picker}
|
||||
show_pid={show_pid}
|
||||
search_param={search_param}
|
||||
/>
|
||||
))}
|
||||
{this.state.replies
|
||||
.slice(0, PREVIEW_REPLY_COUNT)
|
||||
.map(
|
||||
(reply) =>
|
||||
!reply.blocked && (
|
||||
<Reply
|
||||
key={reply.cid}
|
||||
info={reply}
|
||||
color_picker={this.color_picker}
|
||||
show_pid={show_pid}
|
||||
search_param={search_param}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
{this.state.replies.length > PREVIEW_REPLY_COUNT && (
|
||||
<div className="box box-tip">
|
||||
还有 {this.state.replies.length - PREVIEW_REPLY_COUNT} 条
|
||||
@@ -1007,58 +1040,60 @@ class FlowItemRow extends PureComponent {
|
||||
);
|
||||
|
||||
if (this.state.hidden) {
|
||||
return this.needFold && (
|
||||
<div
|
||||
className="flow-item-row flow-item-row-with-prompt"
|
||||
onClick={(event) => {
|
||||
if (!CLICKABLE_TAGS[event.target.tagName.toLowerCase()])
|
||||
this.show_sidebar();
|
||||
}}
|
||||
>
|
||||
return (
|
||||
this.needFold && (
|
||||
<div
|
||||
className={
|
||||
'flow-item' + (this.props.is_quote ? ' flow-item-quote' : '')
|
||||
}
|
||||
className="flow-item-row flow-item-row-with-prompt"
|
||||
onClick={(event) => {
|
||||
if (!CLICKABLE_TAGS[event.target.tagName.toLowerCase()])
|
||||
this.show_sidebar();
|
||||
}}
|
||||
>
|
||||
{!!this.props.is_quote && (
|
||||
<div className="quote-tip black-outline">
|
||||
<div>
|
||||
<span className="icon icon-quote" />
|
||||
<div
|
||||
className={
|
||||
'flow-item' + (this.props.is_quote ? ' flow-item-quote' : '')
|
||||
}
|
||||
>
|
||||
{!!this.props.is_quote && (
|
||||
<div className="quote-tip black-outline">
|
||||
<div>
|
||||
<span className="icon icon-quote" />
|
||||
</div>
|
||||
{/*<div>*/}
|
||||
{/* <small>提到</small>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
{/*<div>*/}
|
||||
{/* <small>提到</small>*/}
|
||||
{/*</div>*/}
|
||||
</div>
|
||||
)}
|
||||
<div className="box">
|
||||
<div className="box-header">
|
||||
{!!this.props.do_filter_name && (
|
||||
<span
|
||||
className="reply-header-badge clickable"
|
||||
onClick={() => {
|
||||
this.props.do_filter_name(DZ_NAME);
|
||||
}}
|
||||
>
|
||||
<span className="icon icon-locate" />
|
||||
)}
|
||||
<div className="box">
|
||||
<div className="box-header">
|
||||
{!!this.props.do_filter_name && (
|
||||
<span
|
||||
className="reply-header-badge clickable"
|
||||
onClick={() => {
|
||||
this.props.do_filter_name(DZ_NAME);
|
||||
}}
|
||||
>
|
||||
<span className="icon icon-locate" />
|
||||
</span>
|
||||
)}
|
||||
<code className="box-id">#{this.props.info.pid}</code>
|
||||
|
||||
{this.props.info.author_title && (
|
||||
<span className="box-header-name author-title">{`"${this.props.info.author_title}"`}</span>
|
||||
)}
|
||||
{this.props.info.cw !== null && (
|
||||
<span className="box-header-cw">{this.props.info.cw}</span>
|
||||
)}
|
||||
<Time stamp={this.props.info.timestamp} short={true} />
|
||||
<span className="box-header-badge">
|
||||
{this.needFold ? '已折叠' : '已屏蔽'}
|
||||
</span>
|
||||
)}
|
||||
<code className="box-id">#{this.props.info.pid}</code>
|
||||
|
||||
{this.props.info.author_title && (
|
||||
<span className="box-header-name author-title">{`"${this.props.info.author_title}"`}</span>
|
||||
)}
|
||||
{this.props.info.cw !== null && (
|
||||
<span className="box-header-cw">{this.props.info.cw}</span>
|
||||
)}
|
||||
<Time stamp={this.props.info.timestamp} short={true} />
|
||||
<span className="box-header-badge">
|
||||
{this.needFold ? '已折叠' : '已屏蔽'}
|
||||
</span>
|
||||
<div style={{ clear: 'both' }} />
|
||||
<div style={{ clear: 'both' }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1163,37 +1198,40 @@ function FlowChunk(props) {
|
||||
{({ value: token }) => (
|
||||
<div className="flow-chunk">
|
||||
{!!props.title && <TitleLine text={props.title} />}
|
||||
{props.list.map((info, ind) => !info.blocked && (
|
||||
<LazyLoad
|
||||
key={info.key || info.pid}
|
||||
offset={500}
|
||||
height="15em"
|
||||
hiddenIfInvisible={false}
|
||||
>
|
||||
<div>
|
||||
{!!(
|
||||
props.deletion_detect &&
|
||||
props.mode === 'list' &&
|
||||
ind &&
|
||||
props.list[ind - 1].pid - info.pid > 1
|
||||
) && (
|
||||
<div className="flow-item-row">
|
||||
<div className="box box-tip flow-item box-danger">
|
||||
{props.list[ind - 1].pid - info.pid - 1} 条被删除
|
||||
</div>
|
||||
{props.list.map(
|
||||
(info, ind) =>
|
||||
!info.blocked && (
|
||||
<LazyLoad
|
||||
key={info.key || info.pid}
|
||||
offset={500}
|
||||
height="15em"
|
||||
hiddenIfInvisible={false}
|
||||
>
|
||||
<div>
|
||||
{!!(
|
||||
props.deletion_detect &&
|
||||
props.mode === 'list' &&
|
||||
ind &&
|
||||
props.list[ind - 1].pid - info.pid > 1
|
||||
) && (
|
||||
<div className="flow-item-row">
|
||||
<div className="box box-tip flow-item box-danger">
|
||||
{props.list[ind - 1].pid - info.pid - 1} 条被删除
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<FlowItemRow
|
||||
info={info}
|
||||
mode={props.mode}
|
||||
show_sidebar={props.show_sidebar}
|
||||
token={token}
|
||||
deletion_detect={props.deletion_detect}
|
||||
search_param={props.search_param}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<FlowItemRow
|
||||
info={info}
|
||||
mode={props.mode}
|
||||
show_sidebar={props.show_sidebar}
|
||||
token={token}
|
||||
deletion_detect={props.deletion_detect}
|
||||
search_param={props.search_param}
|
||||
/>
|
||||
</div>
|
||||
</LazyLoad>
|
||||
))}
|
||||
</LazyLoad>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</TokenCtx.Consumer>
|
||||
@@ -1205,23 +1243,23 @@ export class Flow extends PureComponent {
|
||||
super(props);
|
||||
let submode = window[props.mode.toUpperCase() + '_SUBMODE_BACKUP'];
|
||||
if (submode === undefined) {
|
||||
submode = props.mode === 'list' ? (window.config.by_c ? 1 : 0) : 0;
|
||||
submode = props.mode === 'list' ? (window.config.by_c ? 1 : 0) : 0;
|
||||
}
|
||||
this.state = {
|
||||
submode: submode,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
get_submode_names(mode) {
|
||||
switch(mode) {
|
||||
case('list'):
|
||||
switch (mode) {
|
||||
case 'list':
|
||||
return ['最新', '最近回复', '近期热门', '随机'];
|
||||
case('attention'):
|
||||
case 'attention':
|
||||
return ['线上关注', '本地收藏'];
|
||||
case('search'):
|
||||
return ['Tag搜索', '全文搜索', '头衔']
|
||||
case 'search':
|
||||
return ['Tag搜索', '全文搜索', '头衔'];
|
||||
}
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
|
||||
set_submode(submode) {
|
||||
@@ -1233,7 +1271,7 @@ export class Flow extends PureComponent {
|
||||
|
||||
render() {
|
||||
const { submode } = this.state;
|
||||
const submode_names = this.get_submode_names(this.props.mode)
|
||||
const submode_names = this.get_submode_names(this.props.mode);
|
||||
return (
|
||||
<>
|
||||
<div className="aux-margin flow-submode-choice">
|
||||
@@ -1257,11 +1295,10 @@ export class Flow extends PureComponent {
|
||||
token={this.props.token}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SubFlow extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -1406,11 +1443,13 @@ class SubFlow extends PureComponent {
|
||||
? json.data
|
||||
: !use_regex
|
||||
? json.data.filter((post) => {
|
||||
return this.state.search_param
|
||||
.split(' ')
|
||||
.every((keyword) => post.text.includes(keyword));
|
||||
return this.state.search_param
|
||||
.split(' ')
|
||||
.every((keyword) => post.text.includes(keyword));
|
||||
}) // Not using regex
|
||||
: json.data.filter((post) => !!post.text.match(regex_search)), // Using regex
|
||||
: json.data.filter(
|
||||
(post) => !!post.text.match(regex_search),
|
||||
), // Using regex
|
||||
},
|
||||
mode: 'attention_finished',
|
||||
loading_status: 'done',
|
||||
@@ -1419,18 +1458,18 @@ class SubFlow extends PureComponent {
|
||||
window.saved_attentions = Array.from(
|
||||
new Set([
|
||||
...window.saved_attentions,
|
||||
...json.data.map(post => post.pid)
|
||||
])
|
||||
).sort((a, b) => (b - a));
|
||||
...json.data.map((post) => post.pid),
|
||||
]),
|
||||
).sort((a, b) => b - a);
|
||||
save_attentions();
|
||||
}
|
||||
})
|
||||
.catch(failed);
|
||||
} else if (this.props.submode === 1) {
|
||||
const PERPAGE = 50;
|
||||
let pids = window.saved_attentions.sort(
|
||||
(a, b) => (b - a)
|
||||
).slice((page - 1) * PERPAGE, page * PERPAGE);
|
||||
let pids = window.saved_attentions
|
||||
.sort((a, b) => b - a)
|
||||
.slice((page - 1) * PERPAGE, page * PERPAGE);
|
||||
if (pids.length) {
|
||||
API.get_multi(pids, this.props.token)
|
||||
.then((json) => {
|
||||
@@ -1458,7 +1497,7 @@ class SubFlow extends PureComponent {
|
||||
console.log('local attention finished');
|
||||
this.setState({
|
||||
loading_status: 'done',
|
||||
mode: 'attention_finished'
|
||||
mode: 'attention_finished',
|
||||
});
|
||||
return;
|
||||
}
|
||||
@@ -1496,18 +1535,23 @@ class SubFlow extends PureComponent {
|
||||
}
|
||||
|
||||
trunc_string(s, max_len) {
|
||||
return s.substr(0, max_len) + (
|
||||
s.length > max_len ? '...' : ''
|
||||
)
|
||||
return s.substr(0, max_len) + (s.length > max_len ? '...' : '');
|
||||
}
|
||||
|
||||
gen_export() {
|
||||
this.setState({
|
||||
can_export: false,
|
||||
export_text: "以下是你关注的洞及摘要,复制保存到本地吧。\n\n" + this.state.chunks.data.map(
|
||||
p => `#${p.pid}: ${
|
||||
this.trunc_string(p.text.replaceAll('\n', ' '), 50)
|
||||
}`).join('\n\n')
|
||||
export_text:
|
||||
'以下是你关注的洞及摘要,复制保存到本地吧。\n\n' +
|
||||
this.state.chunks.data
|
||||
.map(
|
||||
(p) =>
|
||||
`#${p.pid}: ${this.trunc_string(
|
||||
p.text.replaceAll('\n', ' '),
|
||||
50,
|
||||
)}`,
|
||||
)
|
||||
.join('\n\n'),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1515,9 +1559,14 @@ class SubFlow extends PureComponent {
|
||||
const should_deletion_detect = localStorage['DELETION_DETECT'] === 'on';
|
||||
return (
|
||||
<div className="flow-container">
|
||||
|
||||
{this.state.mode === 'attention_finished' && this.props.submode == 0 && (
|
||||
<button className="export-btn" type="button" onClick={this.gen_export.bind(this)}>导出</button>
|
||||
<button
|
||||
className="export-btn"
|
||||
type="button"
|
||||
onClick={this.gen_export.bind(this)}
|
||||
>
|
||||
导出
|
||||
</button>
|
||||
)}
|
||||
|
||||
{this.state.export_text && (
|
||||
|
||||
Reference in New Issue
Block a user