update
This commit is contained in:
@@ -18,14 +18,17 @@ function pad2(x) {
|
|||||||
return x<10 ? '0'+x : ''+x;
|
return x<10 ? '0'+x : ''+x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function format_time(time) {
|
||||||
|
return `${time.getMonth()+1}-${pad2(time.getDate())} ${time.getHours()}:${pad2(time.getMinutes())}:${pad2(time.getSeconds())}`;
|
||||||
|
}
|
||||||
|
|
||||||
export function Time(props) {
|
export function Time(props) {
|
||||||
const time=new Date(props.stamp*1000);
|
const time=new Date(props.stamp*1000);
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
<TimeAgo date={time} formatter={chinese_format} />
|
<TimeAgo date={time} formatter={chinese_format} />
|
||||||
|
|
||||||
{time.getMonth()+1}-{time.getDate()}
|
{format_time(time)}
|
||||||
{time.getHours()}:{pad2(time.getMinutes())}
|
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -102,7 +105,7 @@ export function PromotionBar(props) {
|
|||||||
return is_ios ? (
|
return is_ios ? (
|
||||||
<div className="box promotion-bar">
|
<div className="box promotion-bar">
|
||||||
<span className="icon icon-about" />
|
<span className="icon icon-about" />
|
||||||
在 Safari 中将本网站 <b>添加到主屏幕</b> 更好用哦
|
用 Safari 将本网站 <b>添加到主屏幕</b> 更好用
|
||||||
</div>
|
</div>
|
||||||
) : null;
|
) : null;
|
||||||
}
|
}
|
||||||
@@ -113,6 +113,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.box-header {
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
.flow-item-row p.img {
|
.flow-item-row p.img {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
@@ -129,10 +133,6 @@
|
|||||||
margin: 0 .5em;
|
margin: 0 .5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-id {
|
|
||||||
opacity: .6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flow-item-dot {
|
.flow-item-dot {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: calc(-.5em - 5px);
|
top: calc(-.5em - 5px);
|
||||||
@@ -144,3 +144,7 @@
|
|||||||
background-color: orange;
|
background-color: orange;
|
||||||
box-shadow: 0 0 5px rgba(0,0,0,.4);
|
box-shadow: 0 0 5px rgba(0,0,0,.4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.box-content {
|
||||||
|
margin: .5em 0;
|
||||||
|
}
|
||||||
44
src/Flows.js
44
src/Flows.js
@@ -1,7 +1,7 @@
|
|||||||
import React, {Component, PureComponent} from 'react';
|
import React, {Component, PureComponent} from 'react';
|
||||||
import copy from 'copy-to-clipboard';
|
import copy from 'copy-to-clipboard';
|
||||||
import {ColorPicker} from './color_picker';
|
import {ColorPicker} from './color_picker';
|
||||||
import {Time, TitleLine, HighlightedText} from './Common';
|
import {format_time, Time, TitleLine, HighlightedText} from './Common';
|
||||||
import './Flows.css';
|
import './Flows.css';
|
||||||
import LazyLoad from 'react-lazyload';
|
import LazyLoad from 'react-lazyload';
|
||||||
import {AudioWidget} from './AudioWidget';
|
import {AudioWidget} from './AudioWidget';
|
||||||
@@ -38,6 +38,7 @@ function load_single_meta(show_sidebar,token) {
|
|||||||
<FlowSidebar
|
<FlowSidebar
|
||||||
info={single.data} replies={replies.data} attention={replies.attention}
|
info={single.data} replies={replies.data} attention={replies.attention}
|
||||||
token={token} show_sidebar={show_sidebar} color_picker={color_picker}
|
token={token} show_sidebar={show_sidebar} color_picker={color_picker}
|
||||||
|
deletion_detect={localStorage['DELETION_DETECT']==='on'}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
@@ -62,15 +63,22 @@ function Reply(props) {
|
|||||||
<code className="box-id">#{props.info.cid}</code>
|
<code className="box-id">#{props.info.cid}</code>
|
||||||
<Time stamp={props.info.timestamp} />
|
<Time stamp={props.info.timestamp} />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="box-content">
|
||||||
<HighlightedText text={props.info.text} color_picker={props.color_picker} show_pid={props.show_pid} />
|
<HighlightedText text={props.info.text} color_picker={props.color_picker} show_pid={props.show_pid} />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function FlowItem(props) {
|
function FlowItem(props) {
|
||||||
function copy_link(event) {
|
function copy_link(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
copy(event.target.href);
|
copy(
|
||||||
|
`${event.target.href}\n`+
|
||||||
|
`(${format_time(new Date(props.info.timestamp*1000))} ${props.info.likenum}赞 ${props.info.reply}回复)\n`+
|
||||||
|
`${props.info.text}${props.info.type==='image'?' [图片]':props.info.type==='audio'?' [语音]':''}\n`+
|
||||||
|
props.replies.map((r)=>(r.text)).join('\n')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -93,6 +101,7 @@ function FlowItem(props) {
|
|||||||
|
|
||||||
<Time stamp={props.info.timestamp} />
|
<Time stamp={props.info.timestamp} />
|
||||||
</div>
|
</div>
|
||||||
|
<div className="box-content">
|
||||||
<HighlightedText text={props.info.text} color_picker={props.color_picker} show_pid={props.show_pid} />
|
<HighlightedText text={props.info.text} color_picker={props.color_picker} show_pid={props.show_pid} />
|
||||||
{props.info.type==='image' &&
|
{props.info.type==='image' &&
|
||||||
<p className="img">
|
<p className="img">
|
||||||
@@ -104,6 +113,7 @@ function FlowItem(props) {
|
|||||||
}
|
}
|
||||||
{props.info.type==='audio' && <AudioWidget src={AUDIO_BASE+props.info.url} />}
|
{props.info.type==='audio' && <AudioWidget src={AUDIO_BASE+props.info.url} />}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,9 +139,6 @@ class FlowSidebar extends PureComponent {
|
|||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
this.setState((prev,props)=>({
|
this.setState((prev,props)=>({
|
||||||
replies: json.data,
|
replies: json.data,
|
||||||
info: Object.assign({}, prev.info, {
|
|
||||||
reply: ''+json.data.length,
|
|
||||||
}),
|
|
||||||
attention: !!json.attention,
|
attention: !!json.attention,
|
||||||
loading_status: 'done',
|
loading_status: 'done',
|
||||||
}), ()=>{
|
}), ()=>{
|
||||||
@@ -213,20 +220,20 @@ class FlowSidebar extends PureComponent {
|
|||||||
return (
|
return (
|
||||||
<div className="flow-item-row sidebar-flow-item">
|
<div className="flow-item-row sidebar-flow-item">
|
||||||
<div className="box box-tip">
|
<div className="box box-tip">
|
||||||
{star_brush &&
|
{(star_brush && !!this.props.token) &&
|
||||||
<span>
|
<span>
|
||||||
<a onClick={this.star_brush.bind(this)}>-</a>
|
<a onClick={this.star_brush.bind(this)}>-</a>
|
||||||
/
|
/
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
{this.props.token &&
|
{!!this.props.token &&
|
||||||
<span>
|
<span>
|
||||||
<a onClick={this.report.bind(this)}>举报</a>
|
<a onClick={this.report.bind(this)}>举报</a>
|
||||||
/
|
/
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
<a onClick={this.load_replies.bind(this)}>刷新回复</a>
|
<a onClick={this.load_replies.bind(this)}>刷新回复</a>
|
||||||
{this.props.token &&
|
{!!this.props.token &&
|
||||||
<span>
|
<span>
|
||||||
/
|
/
|
||||||
<a onClick={()=>{
|
<a onClick={()=>{
|
||||||
@@ -241,14 +248,20 @@ class FlowSidebar extends PureComponent {
|
|||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<FlowItem info={this.state.info} attention={this.state.attention} img_clickable={true}
|
<FlowItem info={this.state.info} attention={this.state.attention} img_clickable={true}
|
||||||
color_picker={this.color_picker} show_pid={this.show_pid} />
|
color_picker={this.color_picker} show_pid={this.show_pid} replies={this.state.replies} />
|
||||||
|
{(this.props.deletion_detect && parseInt(this.state.info.reply)!==this.state.replies.length) &&
|
||||||
|
<div className="box box-tip flow-item box-danger">
|
||||||
|
{parseInt(this.state.info.reply)-this.state.replies.length} 条回复被删除
|
||||||
|
</div>
|
||||||
|
}
|
||||||
{this.state.replies.map((reply)=>(
|
{this.state.replies.map((reply)=>(
|
||||||
<LazyLoad key={reply.cid} offset={500} height="5em" overflow={true} once={true}>
|
<LazyLoad key={reply.cid} offset={500} height="5em" overflow={true} once={true}>
|
||||||
<Reply info={reply} color_picker={this.color_picker} show_pid={this.show_pid} />
|
<Reply info={reply} color_picker={this.color_picker} show_pid={this.show_pid} />
|
||||||
</LazyLoad>
|
</LazyLoad>
|
||||||
))}
|
))}
|
||||||
{this.props.token &&
|
{!!this.props.token ?
|
||||||
<ReplyForm pid={this.state.info.pid} token={this.props.token} on_complete={this.load_replies.bind(this)} />
|
<ReplyForm pid={this.state.info.pid} token={this.props.token} on_complete={this.load_replies.bind(this)} /> :
|
||||||
|
<div className="box box-tip flow-item">登录后可以回复树洞</div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -283,9 +296,6 @@ class FlowItemRow extends PureComponent {
|
|||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
this.setState((prev,props)=>({
|
this.setState((prev,props)=>({
|
||||||
replies: json.data,
|
replies: json.data,
|
||||||
info: Object.assign({}, prev.info, {
|
|
||||||
reply: ''+json.data.length,
|
|
||||||
}),
|
|
||||||
attention: !!json.attention,
|
attention: !!json.attention,
|
||||||
reply_status: 'done',
|
reply_status: 'done',
|
||||||
}),callback);
|
}),callback);
|
||||||
@@ -305,6 +315,7 @@ class FlowItemRow extends PureComponent {
|
|||||||
<FlowSidebar
|
<FlowSidebar
|
||||||
info={this.state.info} replies={this.state.replies} attention={this.state.attention} sync_state={this.setState.bind(this)}
|
info={this.state.info} replies={this.state.replies} attention={this.state.attention} sync_state={this.setState.bind(this)}
|
||||||
token={this.props.token} show_sidebar={this.props.show_sidebar} color_picker={this.color_picker}
|
token={this.props.token} show_sidebar={this.props.show_sidebar} color_picker={this.color_picker}
|
||||||
|
deletion_detect={this.props.deletion_detect}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -316,7 +327,7 @@ class FlowItemRow extends PureComponent {
|
|||||||
this.show_sidebar();
|
this.show_sidebar();
|
||||||
}}>
|
}}>
|
||||||
<FlowItem info={this.state.info} attention={this.state.attention} img_clickable={false}
|
<FlowItem info={this.state.info} attention={this.state.attention} img_clickable={false}
|
||||||
color_picker={this.color_picker} show_pid={this.show_pid} />
|
color_picker={this.color_picker} show_pid={this.show_pid} replies={this.state.replies} />
|
||||||
<div className="flow-reply-row">
|
<div className="flow-reply-row">
|
||||||
{this.state.reply_status==='loading' && <div className="box box-tip">加载中</div>}
|
{this.state.reply_status==='loading' && <div className="box box-tip">加载中</div>}
|
||||||
{this.state.reply_status==='failed' &&
|
{this.state.reply_status==='failed' &&
|
||||||
@@ -349,7 +360,8 @@ function FlowChunk(props) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
<FlowItemRow info={info} show_sidebar={props.show_sidebar} token={token} />
|
<FlowItemRow info={info} show_sidebar={props.show_sidebar} token={token}
|
||||||
|
deletion_detect={props.deletion_detect} />
|
||||||
</div>
|
</div>
|
||||||
</LazyLoad>
|
</LazyLoad>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: calc(100% - 700px);
|
width: calc(100% - 700px);
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
background-color: rgba(255,255,255,.8);
|
background-color: rgba(255,255,255,.7);
|
||||||
z-index: 21;
|
z-index: 21;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ export class LoginForm extends Component {
|
|||||||
请勿泄露 Token,它代表您的登录状态,与您的账户唯一对应且泄露后无法重置
|
请勿泄露 Token,它代表您的登录状态,与您的账户唯一对应且泄露后无法重置
|
||||||
</p>
|
</p>
|
||||||
</div> :
|
</div> :
|
||||||
|
<div>
|
||||||
<p>登录后可以使用关注、回复等功能</p>
|
<p>登录后可以使用关注、回复等功能</p>
|
||||||
}
|
|
||||||
<p>
|
<p>
|
||||||
<label>
|
<label>
|
||||||
学号
|
学号
|
||||||
@@ -129,6 +129,8 @@ export class LoginForm extends Component {
|
|||||||
我们不会记录或使用您的登录信息
|
我们不会记录或使用您的登录信息
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
}</TokenCtx.Consumer>
|
}</TokenCtx.Consumer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ body, textarea, pre {
|
|||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p, pre {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user