import React, {Component, PureComponent} from 'react'; import {ColorPicker} from './color_picker'; import {Time, TitleLine, HighlightedText} from './Common.js'; import './Flows.css'; import LazyLoad from 'react-lazyload'; import {AudioWidget} from './AudioWidget.js'; import {TokenCtx} from './UserAction'; const IMAGE_BASE='http://www.pkuhelper.com/services/pkuhole/images/'; const AUDIO_BASE='/audio_proxy/'; const API_BASE=window.location.protocol==='https:' ? '/api_proxy' : 'http://www.pkuhelper.com/services/pkuhole'; const SEARCH_PAGESIZE=50; const CLICKABLE_TAGS={a: true, audio: true}; const PREVIEW_REPLY_COUNT=10; window.LATEST_POST_ID=parseInt(localStorage['_LATEST_POST_ID'],10)||0; function Reply(props) { return (
#{props.info.cid} 
); } function FlowItem(props) { return (
{parseInt(props.info.pid,10)>window.LATEST_POST_ID &&
}
{!!parseInt(props.info.likenum,10) && {props.info.likenum}  } {!!parseInt(props.info.reply,10) && {props.info.reply}  } #{props.info.pid} 
{props.info.type==='image' ?

: null} {props.info.type==='audio' ? : null}
); } class FlowItemRow extends PureComponent { constructor(props) { super(props); this.state={ replies: [], reply_status: 'done', info: props.info, attention: false, }; this.color_picker=new ColorPicker(); } componentDidMount() { if(parseInt(this.state.info.reply,10)) { this.load_replies(); } } load_replies(callback) { console.log('fetching reply',this.state.info.pid); this.setState({ reply_status: 'loading', }); const token_param=this.props.token ? '&token='+this.props.token : ''; fetch( API_BASE+'/api.php?action=getcomment'+ '&pid='+this.state.info.pid+ token_param ) .then((res)=>res.json()) .then((json)=>{ if(json.code!==0) throw new Error(json); const replies=json.data .sort((a,b)=>{ return parseInt(a.timestamp,10)-parseInt(b.timestamp,10); }) .map((info)=>{ info._display_color=this.color_picker.get(info.name); return info; }); this.setState((prev,props)=>({ replies: replies, info: Object.assign({}, prev.info, { reply: ''+replies.length, }), attention: !!json.attention, reply_status: 'done', }),callback); }) .catch((e)=>{ console.trace(e); this.setState({ replies: [], reply_status: 'failed', },callback); }); } show_sidebar() { this.props.show_sidebar( '帖子详情',
{ this.props.show_sidebar('帖子详情',

加载中……

); this.load_replies(this.show_sidebar); }}>刷新回复
{this.state.replies.map((reply)=>( ))}
); } render() { // props.do_show_details return (
{ if(!CLICKABLE_TAGS[event.target.tagName.toLowerCase()]) this.show_sidebar(); }}>
{this.state.reply_status==='loading' &&
加载中
} {this.state.reply_status==='failed' &&
{this.load_replies()}}>重新加载
} {this.state.replies.slice(0,PREVIEW_REPLY_COUNT).map((reply)=>( ))} {this.state.replies.length>PREVIEW_REPLY_COUNT &&
还有 {this.state.replies.length-PREVIEW_REPLY_COUNT} 条
}
); } } function FlowChunk(props) { return ( {({value: token})=>(
{props.list.map((info)=>( ))}
)}
); } export class Flow extends PureComponent { constructor(props) { super(props); this.state={ mode: props.mode, search_param: props.search_text, loaded_pages: 0, chunks: [], loading_status: 'done', }; this.on_scroll_bound=this.on_scroll.bind(this); window.LATEST_POST_ID=parseInt(localStorage['_LATEST_POST_ID'],10)||0; } load_page(page) { const failed=(err)=>{ console.trace(err); this.setState((prev,props)=>({ loaded_pages: prev.loaded_pages-1, loading_status: 'failed', })); }; const token_param=this.props.token ? '&token='+this.props.token : ''; if(page>this.state.loaded_pages+1) throw new Error('bad page'); if(page===this.state.loaded_pages+1) { console.log('fetching page',page); if(this.state.mode==='list') { fetch( API_BASE+'/api.php?action=getlist'+ '&p='+page+ token_param ) .then((res)=>res.json()) .then((json)=>{ if(json.code!==0) throw new Error(json); json.data.forEach((x)=>{ if(parseInt(x.pid,10)>(parseInt(localStorage['_LATEST_POST_ID'],10)||0)) localStorage['_LATEST_POST_ID']=x.pid; }); this.setState((prev,props)=>({ chunks: prev.chunks.concat([{ title: 'Page '+page, data: json.data.filter((x)=>( prev.chunks.length===0 || !(prev.chunks[prev.chunks.length-1].data.some((p)=>p.pid===x.pid)) )), }]), loading_status: 'done', })); }) .catch(failed); } else if(this.state.mode==='search') { fetch( API_BASE+'/api.php?action=search'+ '&pagesize='+SEARCH_PAGESIZE*page+ '&keywords='+encodeURIComponent(this.state.search_param)+ token_param ) .then((res)=>res.json()) .then((json)=>{ if(json.code!==0) throw new Error(json); const finished=json.data.lengthres.json()) .then((json)=>{ if(json.code!==0) throw new Error(json); this.setState({ chunks: [{ title: 'Attention List', data: json.data, }], mode: 'attention_finished', loading_status: 'done', }); }) .catch(failed); } else { console.log('nothing to load'); return; } this.setState((prev,props)=>({ loaded_pages: prev.loaded_pages+1, loading_status: 'loading', })); } } on_scroll(event) { if(event.target===document) { const avail=document.body.scrollHeight-window.scrollY-window.innerHeight; if(avail {this.state.chunks.map((chunk)=>( ))} {this.state.loading_status==='failed' &&
{this.load_page(this.state.loaded_pages+1)}}>重新加载
}
); } }