forked from newthuhole/hole_thu_frontend
update
- add msg viewer - re-add hole.xmcp.ml deprecation alert - add http error detection - add freshman welcome
This commit is contained in:
10
src/App.js
10
src/App.js
@@ -9,6 +9,16 @@ import {load_config,bgimg_style} from './Config';
|
|||||||
import ImasuguApp from './imasugu/src/App';
|
import ImasuguApp from './imasugu/src/App';
|
||||||
|
|
||||||
function DeprecatedAlert(props) {
|
function DeprecatedAlert(props) {
|
||||||
|
if(document.domain==='hole.xmcp.ml')
|
||||||
|
return (
|
||||||
|
<div className="flow-item">
|
||||||
|
<div className="box box-tip">
|
||||||
|
<p><b>请使用新域名访问P大树洞!</b></p>
|
||||||
|
<p><a href="http://pkuhelper.pku.edu.cn/hole/">pkuhelper.pku.edu.cn/hole</a></p>
|
||||||
|
<p>当前域名将停止支持</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
65
src/Message.js
Normal file
65
src/Message.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
import React, {Component, PureComponent} from 'react';
|
||||||
|
import {PKUHELPER_ROOT,get_json} from './flows_api';
|
||||||
|
import {Time} from './Common';
|
||||||
|
|
||||||
|
export class MessageViewer extends PureComponent {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state={
|
||||||
|
loading_status: 'idle',
|
||||||
|
msg: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.load();
|
||||||
|
}
|
||||||
|
|
||||||
|
load() {
|
||||||
|
if(this.state.loading_status==='loading') return;
|
||||||
|
this.setState({
|
||||||
|
loading_status: 'loading',
|
||||||
|
},()=>{
|
||||||
|
fetch(PKUHELPER_ROOT+'api_xmcp/hole/system_msg?user_token='+encodeURIComponent(this.props.token))
|
||||||
|
.then(get_json)
|
||||||
|
.then((json)=>{
|
||||||
|
if(json.error)
|
||||||
|
throw new Error(json.error);
|
||||||
|
else
|
||||||
|
this.setState({
|
||||||
|
loading_status: 'done',
|
||||||
|
msg: json.result,
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch((err)=>{
|
||||||
|
console.error(err);
|
||||||
|
alert(''+err);
|
||||||
|
this.setState({
|
||||||
|
loading_status: 'failed',
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if(this.state.loading_status==='loading')
|
||||||
|
return (<p className="box box-tip">加载中……</p>);
|
||||||
|
else if(this.state.loading_status==='failed')
|
||||||
|
return (<div className="box box-tip"><a onClick={()=>{this.load()}}>重新加载</a></div>);
|
||||||
|
else if(this.state.loading_status==='done')
|
||||||
|
return this.state.msg.map((msg)=>(
|
||||||
|
<div className="box">
|
||||||
|
<div className="box-header">
|
||||||
|
<Time stamp={msg.timestamp} />
|
||||||
|
<b>{msg.title}</b>
|
||||||
|
</div>
|
||||||
|
<div className="box-content">
|
||||||
|
<pre>{msg.content}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
));
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -116,7 +116,7 @@ class ControlBar extends PureComponent {
|
|||||||
'P大树洞 网页版',
|
'P大树洞 网页版',
|
||||||
<div>
|
<div>
|
||||||
<PromotionBar />
|
<PromotionBar />
|
||||||
<LoginForm />
|
<LoginForm show_sidebar={this.props.show_sidebar} />
|
||||||
<div className="box list-menu">
|
<div className="box list-menu">
|
||||||
<a onClick={()=>{this.props.show_sidebar(
|
<a onClick={()=>{this.props.show_sidebar(
|
||||||
'设置',
|
'设置',
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
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 {SafeTextarea} from './Common';
|
import {SafeTextarea} from './Common';
|
||||||
import {API_VERSION_PARAM,PKUHELPER_ROOT,API} from './flows_api'
|
import {API_VERSION_PARAM,PKUHELPER_ROOT,API,get_json} from './flows_api'
|
||||||
import md5 from 'md5';
|
import md5 from 'md5';
|
||||||
|
|
||||||
import './UserAction.css';
|
import './UserAction.css';
|
||||||
|
|
||||||
import {API_BASE} from './Common';
|
import {API_BASE} from './Common';
|
||||||
|
import {MessageViewer} from './Message';
|
||||||
const LOGIN_BASE=PKUHELPER_ROOT+'services/login';
|
const LOGIN_BASE=PKUHELPER_ROOT+'services/login';
|
||||||
const MAX_IMG_PX=2500;
|
const MAX_IMG_PX=2500;
|
||||||
const MAX_IMG_FILESIZE=300000;
|
const MAX_IMG_FILESIZE=300000;
|
||||||
@@ -68,15 +69,16 @@ export class LoginForm extends Component {
|
|||||||
},
|
},
|
||||||
body: data,
|
body: data,
|
||||||
})
|
})
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0) {
|
if(json.code!==0) {
|
||||||
if(json.msg) alert(json.msg);
|
if(json.msg) alert(json.msg);
|
||||||
throw new Error(JSON.stringify(json));
|
throw new Error(JSON.stringify(json));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let freshman_welcome=json.uid.indexOf('19')===0 && (+new Date())<1567958400000; // 2019-09-09 0:00 GMT+8
|
||||||
set_token(json.user_token);
|
set_token(json.user_token);
|
||||||
alert(`成功以 ${json.name} 的身份登录`);
|
alert(`成功以 ${json.name} 的身份登录`+(freshman_welcome ? '\n欢迎来到北京大学!' : ''));
|
||||||
this.setState({
|
this.setState({
|
||||||
loading_status: 'done',
|
loading_status: 'done',
|
||||||
});
|
});
|
||||||
@@ -131,6 +133,13 @@ export class LoginForm extends Component {
|
|||||||
<b>您已登录。</b>
|
<b>您已登录。</b>
|
||||||
<button type="button" onClick={()=>{token.set_value(null);}}>注销</button>
|
<button type="button" onClick={()=>{token.set_value(null);}}>注销</button>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
<a onClick={()=>{this.props.show_sidebar(
|
||||||
|
'系统消息',
|
||||||
|
<MessageViewer token={token.value} />
|
||||||
|
)}}>查看系统消息</a><br />
|
||||||
|
当您发送的内容违规时,我们将用系统消息提示您
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<a onClick={this.copy_token.bind(this,token.value)}>复制 User Token</a><br />
|
<a onClick={this.copy_token.bind(this,token.value)}>复制 User Token</a><br />
|
||||||
User Token 可用于迁移登录状态,请勿泄露,因为它与您的账户唯一对应且泄露后无法重置
|
User Token 可用于迁移登录状态,请勿泄露,因为它与您的账户唯一对应且泄露后无法重置
|
||||||
@@ -222,7 +231,7 @@ export class ReplyForm extends Component {
|
|||||||
},
|
},
|
||||||
body: data,
|
body: data,
|
||||||
})
|
})
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0) {
|
if(json.code!==0) {
|
||||||
if(json.msg) alert(json.msg);
|
if(json.msg) alert(json.msg);
|
||||||
@@ -248,7 +257,7 @@ export class ReplyForm extends Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<form onSubmit={this.on_submit.bind(this)} className={'reply-form box'+(this.state.text?' reply-sticky':'')}>
|
<form onSubmit={this.on_submit.bind(this)} className={'reply-form box'+(this.state.text?' reply-sticky':'')}>
|
||||||
<SafeTextarea ref={this.area_ref} id={this.props.pid} on_change={this.on_change_bound} on_submit={this.on_submit.bind(this)} />
|
<SafeTextarea key={this.props.pid} ref={this.area_ref} id={this.props.pid} on_change={this.on_change_bound} on_submit={this.on_submit.bind(this)} />
|
||||||
{this.state.loading_status==='loading' ?
|
{this.state.loading_status==='loading' ?
|
||||||
<button disabled="disabled">
|
<button disabled="disabled">
|
||||||
<span className="icon icon-loading" />
|
<span className="icon icon-loading" />
|
||||||
@@ -302,7 +311,7 @@ export class PostForm extends Component {
|
|||||||
},
|
},
|
||||||
body: data,
|
body: data,
|
||||||
})
|
})
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0) {
|
if(json.code!==0) {
|
||||||
if(json.msg) alert(json.msg);
|
if(json.msg) alert(json.msg);
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
import {API_BASE} from './Common';
|
import {API_BASE} from './Common';
|
||||||
|
|
||||||
export const API_VERSION_PARAM='&PKUHelperAPI=3.0';
|
export const API_VERSION_PARAM='&PKUHelperAPI=3.0';
|
||||||
export const PKUHELPER_ROOT= // don't use :10301 if we are already in the same domain
|
export const PKUHELPER_ROOT='//pkuhelper.pku.edu.cn/';
|
||||||
document.domain==='pkuhelper.pku.edu.cn' ? '/' : '//pkuhelper.pku.edu.cn/';
|
|
||||||
|
|
||||||
function token_param(token) {
|
function token_param(token) {
|
||||||
return API_VERSION_PARAM + (token ? ('&user_token='+token) : '');
|
return API_VERSION_PARAM + (token ? ('&user_token='+token) : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function get_json(res) {
|
||||||
|
if(!res.ok) throw Error(`网络错误 ${res.status} ${res.statusText}`);
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
|
||||||
export const API={
|
export const API={
|
||||||
load_replies: (pid,token,color_picker)=>{
|
load_replies: (pid,token,color_picker)=>{
|
||||||
return fetch(
|
return fetch(
|
||||||
@@ -15,7 +19,7 @@ export const API={
|
|||||||
'&pid='+pid+
|
'&pid='+pid+
|
||||||
token_param(token)
|
token_param(token)
|
||||||
)
|
)
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0) {
|
if(json.code!==0) {
|
||||||
if(json.msg) throw new Error(json.msg);
|
if(json.msg) throw new Error(json.msg);
|
||||||
@@ -48,7 +52,7 @@ export const API={
|
|||||||
},
|
},
|
||||||
body: data,
|
body: data,
|
||||||
})
|
})
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0) {
|
if(json.code!==0) {
|
||||||
if(json.msg && json.msg==='已经关注过辣') {}
|
if(json.msg && json.msg==='已经关注过辣') {}
|
||||||
@@ -73,7 +77,7 @@ export const API={
|
|||||||
},
|
},
|
||||||
body: data,
|
body: data,
|
||||||
})
|
})
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0) {
|
if(json.code!==0) {
|
||||||
if(json.msg) alert(json.msg);
|
if(json.msg) alert(json.msg);
|
||||||
@@ -89,7 +93,7 @@ export const API={
|
|||||||
'&p='+page+
|
'&p='+page+
|
||||||
token_param(token)
|
token_param(token)
|
||||||
)
|
)
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0)
|
if(json.code!==0)
|
||||||
throw new Error(JSON.stringify(json));
|
throw new Error(JSON.stringify(json));
|
||||||
@@ -104,7 +108,7 @@ export const API={
|
|||||||
'&keywords='+encodeURIComponent(keyword)+
|
'&keywords='+encodeURIComponent(keyword)+
|
||||||
token_param(token)
|
token_param(token)
|
||||||
)
|
)
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0) {
|
if(json.code!==0) {
|
||||||
if(json.msg) alert(json.msg);
|
if(json.msg) alert(json.msg);
|
||||||
@@ -120,7 +124,7 @@ export const API={
|
|||||||
'&pid='+pid+
|
'&pid='+pid+
|
||||||
token_param(token)
|
token_param(token)
|
||||||
)
|
)
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0) {
|
if(json.code!==0) {
|
||||||
if(json.msg) throw new Error(json.msg);
|
if(json.msg) throw new Error(json.msg);
|
||||||
@@ -135,7 +139,7 @@ export const API={
|
|||||||
API_BASE+'/api.php?action=getattention'+
|
API_BASE+'/api.php?action=getattention'+
|
||||||
token_param(token)
|
token_param(token)
|
||||||
)
|
)
|
||||||
.then((res)=>res.json())
|
.then(get_json)
|
||||||
.then((json)=>{
|
.then((json)=>{
|
||||||
if(json.code!==0) {
|
if(json.code!==0) {
|
||||||
if(json.msg) alert(json.msg);
|
if(json.msg) alert(json.msg);
|
||||||
|
|||||||
Reference in New Issue
Block a user