功能适配与界面调整若干
This commit is contained in:
@@ -26,6 +26,6 @@
|
||||
<title>新T树洞</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">开启javascript,或刷新重试</div>
|
||||
<div id="root">请开启javascript,或稍等片刻</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 67 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 67 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 79 KiB |
@@ -16,7 +16,7 @@ import renderMd from './Markdown';
|
||||
|
||||
export { format_time, Time, TitleLine };
|
||||
|
||||
export const API_BASE = '/_api/v1/';
|
||||
export const API_BASE = '/_api/v1';
|
||||
|
||||
// https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
|
||||
function escape_regex(string) {
|
||||
@@ -164,6 +164,7 @@ export class HighlightedMarkdown extends Component {
|
||||
['url', URL_RE],
|
||||
['pid', PID_RE],
|
||||
['nickname', NICKNAME_RE],
|
||||
//TODO: tag
|
||||
]);
|
||||
|
||||
return (
|
||||
@@ -217,21 +218,7 @@ export class HighlightedMarkdown extends Component {
|
||||
},
|
||||
];
|
||||
const parser = new HtmlToReact.Parser();
|
||||
if (props.author && props.text.match(/^(?:#+ |>|```|\t|\s*-|\s*\d+\.)/)) {
|
||||
const renderedMarkdown = renderMd(props.text);
|
||||
return (
|
||||
<>
|
||||
{props.author}
|
||||
{parser.parseWithInstructions(
|
||||
renderedMarkdown,
|
||||
(node) => node.type !== 'script',
|
||||
processInstructions,
|
||||
) || ''}
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
let rawMd = props.text;
|
||||
if (props.author) rawMd = props.author + ' ' + rawMd;
|
||||
const renderedMarkdown = renderMd(rawMd);
|
||||
return (
|
||||
parser.parseWithInstructions(
|
||||
@@ -241,7 +228,6 @@ export class HighlightedMarkdown extends Component {
|
||||
) || null
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.TEXTAREA_BACKUP = {};
|
||||
@@ -314,6 +300,7 @@ export class SafeTextarea extends Component {
|
||||
onChange={this.on_change_bound}
|
||||
value={this.state.text}
|
||||
onKeyDown={this.on_keydown_bound}
|
||||
maxLength="4096"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@
|
||||
color: white;
|
||||
}
|
||||
|
||||
.box-header-tag {
|
||||
.box-header-cw {
|
||||
color: white;
|
||||
background-color: #00c;
|
||||
font-weight: bold;
|
||||
@@ -263,7 +263,16 @@
|
||||
padding: 0 .25em;
|
||||
}
|
||||
|
||||
.root-dark-mode .box-header-tag {
|
||||
.box-header-name {
|
||||
color: white;
|
||||
background-color: #3338;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
margin-right: .5em;
|
||||
padding: .1em .5em;
|
||||
}
|
||||
|
||||
.root-dark-mode .box-header-cw {
|
||||
background-color: #00a;
|
||||
}
|
||||
|
||||
|
||||
47
src/Flows.js
47
src/Flows.js
@@ -30,19 +30,6 @@ const CLICKABLE_TAGS = { a: true, audio: true };
|
||||
const PREVIEW_REPLY_COUNT = 10;
|
||||
// const QUOTE_BLACKLIST=['23333','233333','66666','666666','10086','10000','100000','99999','999999','55555','555555'];
|
||||
const QUOTE_BLACKLIST = [];
|
||||
const FOLD_TAGS = [
|
||||
'性相关',
|
||||
'政治相关',
|
||||
'性话题',
|
||||
'政治话题',
|
||||
'折叠',
|
||||
'NSFW',
|
||||
'刷屏',
|
||||
'真实性可疑',
|
||||
'用户举报较多',
|
||||
'举报较多',
|
||||
'重复内容',
|
||||
];
|
||||
|
||||
window.LATEST_POST_ID = parseInt(localStorage['_LATEST_POST_ID'], 10) || 0;
|
||||
|
||||
@@ -104,11 +91,8 @@ class Reply extends PureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const replyContent = this.props.info.text;
|
||||
const splitIdx = replyContent.indexOf(']');
|
||||
|
||||
const author = replyContent.substr(0, splitIdx + 1),
|
||||
replyText = replyContent.substr(splitIdx + 2);
|
||||
const author = this.props.info.name,
|
||||
replyText = this.props.info.text;
|
||||
return (
|
||||
<div
|
||||
className={'flow-reply box'}
|
||||
@@ -122,7 +106,6 @@ class Reply extends PureComponent {
|
||||
}
|
||||
>
|
||||
<div className="box-header">
|
||||
<code className="box-id">#{this.props.info.cid}</code>
|
||||
{!!this.props.do_filter_name && (
|
||||
<span
|
||||
className="reply-header-badge clickable"
|
||||
@@ -134,10 +117,12 @@ class Reply extends PureComponent {
|
||||
</span>
|
||||
)}
|
||||
|
||||
{this.props.info.tag !== null && (
|
||||
<span className="box-header-tag">{this.props.info.tag}</span>
|
||||
{(
|
||||
<span className="box-header-name">{this.props.info.name}</span>
|
||||
)}
|
||||
<Time stamp={this.props.info.timestamp} short={false} />
|
||||
|
||||
<code className="box-id">{'$' + this.props.info.cid}</code>
|
||||
</div>
|
||||
<div className="box-content">
|
||||
<HighlightedMarkdown
|
||||
@@ -161,7 +146,7 @@ class FlowItem extends PureComponent {
|
||||
event.preventDefault();
|
||||
copy(
|
||||
`${event.target.href}${
|
||||
this.props.info.tag ? ' 【' + this.props.info.tag + '】' : ''
|
||||
this.props.info.cw ? ' 【' + this.props.info.cw + '】' : ''
|
||||
}\n` +
|
||||
`${this.props.info.text}${
|
||||
this.props.info.type === 'image'
|
||||
@@ -174,7 +159,7 @@ class FlowItem extends PureComponent {
|
||||
this.props.info.likenum
|
||||
}关注 ${this.props.info.reply}回复)\n` +
|
||||
this.props.replies
|
||||
.map((r) => (r.tag ? '【' + r.tag + '】' : '') + r.text)
|
||||
.map((r) => (r.cw ? '【' + r.cw + '】' : '') + r.text)
|
||||
.join('\n'),
|
||||
);
|
||||
}
|
||||
@@ -237,8 +222,8 @@ class FlowItem extends PureComponent {
|
||||
</a>
|
||||
</code>
|
||||
|
||||
{props.info.tag !== null && props.info.tag !== '折叠' && (
|
||||
<span className="box-header-tag">{props.info.tag}</span>
|
||||
{props.info.cw !== null && (
|
||||
<span className="box-header-cw">{props.info.cw}</span>
|
||||
)}
|
||||
<Time stamp={props.info.timestamp} short={!props.img_clickable} />
|
||||
</div>
|
||||
@@ -634,8 +619,7 @@ class FlowSidebar extends PureComponent {
|
||||
class FlowItemRow extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.needFold =
|
||||
FOLD_TAGS.indexOf(props.info.tag) > -1 &&
|
||||
this.needFold = props.info.cw &&
|
||||
(props.search_param === '热榜' || !props.search_param) &&
|
||||
window.config.fold &&
|
||||
props.mode !== 'attention' && props.mode !== 'attention_finished';
|
||||
@@ -861,8 +845,8 @@ class FlowItemRow extends PureComponent {
|
||||
)}
|
||||
<code className="box-id">#{this.props.info.pid}</code>
|
||||
|
||||
{this.props.info.tag !== null && this.props.info.tag !== '折叠' && (
|
||||
<span className="box-header-tag">{this.props.info.tag}</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">
|
||||
@@ -1038,10 +1022,11 @@ export class Flow extends PureComponent {
|
||||
load_page(page) {
|
||||
const failed = (err) => {
|
||||
console.error(err);
|
||||
console.log(err.to_string);
|
||||
this.setState((prev, props) => ({
|
||||
loaded_pages: prev.loaded_pages - 1,
|
||||
loading_status: 'failed',
|
||||
error_msg: '' + err,
|
||||
error_msg: prev.loaded_pages>1 ? '找不到更多了' : '' + err,
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -1219,7 +1204,7 @@ export class Flow extends PureComponent {
|
||||
Loading...
|
||||
</span>
|
||||
) : (
|
||||
'© thuhole'
|
||||
'🄯 2020 copyleft: hole_thu'
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -22,9 +22,8 @@ export class MessageViewer extends PureComponent {
|
||||
},
|
||||
() => {
|
||||
fetch(
|
||||
'/api/v1/system_msg?user_token=' +
|
||||
encodeURIComponent(this.props.token) +
|
||||
API_VERSION_PARAM(),
|
||||
'/_api/v1/system_msg?user_token=' +
|
||||
encodeURIComponent(this.props.token)
|
||||
)
|
||||
.then(get_json)
|
||||
.then((json) => {
|
||||
|
||||
@@ -109,3 +109,9 @@
|
||||
.life-info-error a {
|
||||
--var-link-color: hsl(25,100%,45%);
|
||||
}
|
||||
|
||||
.spoiler-input {
|
||||
width: 100%;
|
||||
margin-bottom: 5px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
@@ -171,6 +171,8 @@ export class LoginForm extends Component {
|
||||
当您发送的内容违规时,我们将用系统消息提示您
|
||||
</p>
|
||||
<p>
|
||||
<small>{token.value}</small>
|
||||
<br/>
|
||||
<a onClick={this.copy_token.bind(this, token.value)}>
|
||||
复制 User Token
|
||||
</a>
|
||||
@@ -263,7 +265,7 @@ export class ReplyForm extends Component {
|
||||
data.append('text', this.state.text);
|
||||
data.append('user_token', this.props.token);
|
||||
fetch(
|
||||
API_BASE + '/api.php?action=docomment' + token_param(this.props.token),
|
||||
API_BASE + '/docomment' + token_param(this.props.token),
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -355,6 +357,7 @@ export class PostForm extends Component {
|
||||
super(props);
|
||||
this.state = {
|
||||
text: '',
|
||||
cw: '',
|
||||
loading_status: 'done',
|
||||
img_tip: null,
|
||||
preview: false,
|
||||
@@ -362,6 +365,7 @@ export class PostForm extends Component {
|
||||
this.img_ref = React.createRef();
|
||||
this.area_ref = React.createRef();
|
||||
this.on_change_bound = this.on_change.bind(this);
|
||||
this.on_cw_change_bound = this.on_cw_change.bind(this);
|
||||
this.on_img_change_bound = this.on_img_change.bind(this);
|
||||
this.color_picker = new ColorPicker();
|
||||
}
|
||||
@@ -370,6 +374,12 @@ export class PostForm extends Component {
|
||||
if (this.area_ref.current) this.area_ref.current.focus();
|
||||
}
|
||||
|
||||
on_cw_change(event) {
|
||||
this.setState({
|
||||
cw: event.target.value,
|
||||
});
|
||||
}
|
||||
|
||||
on_change(value) {
|
||||
this.setState({
|
||||
text: value,
|
||||
@@ -378,12 +388,13 @@ export class PostForm extends Component {
|
||||
|
||||
do_post(text, img) {
|
||||
let data = new URLSearchParams();
|
||||
data.append('cw', this.state.cw);
|
||||
data.append('text', this.state.text);
|
||||
data.append('type', img ? 'image' : 'text');
|
||||
data.append('user_token', this.props.token);
|
||||
if (img) data.append('data', img);
|
||||
|
||||
fetch(API_BASE + '/api.php?action=dopost' + token_param(this.props.token), {
|
||||
fetch(API_BASE + '/dopost' + token_param(this.props.token), {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
@@ -632,12 +643,23 @@ export class PostForm extends Component {
|
||||
/>
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="折叠警告(留空表示不折叠)"
|
||||
value={this.state.cw}
|
||||
id="post_cw"
|
||||
className="spoiler-input"
|
||||
onChange={this.on_cw_change_bound}
|
||||
maxLength="32"
|
||||
/>
|
||||
<SafeTextarea
|
||||
ref={this.area_ref}
|
||||
id="new_post"
|
||||
on_change={this.on_change_bound}
|
||||
on_submit={this.on_submit.bind(this)}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
<p>
|
||||
<small>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { get_json, API_VERSION_PARAM } from './infrastructure/functions';
|
||||
import { get_json} from './infrastructure/functions';
|
||||
import { API_BASE } from './Common';
|
||||
import { cache } from './cache';
|
||||
|
||||
export function token_param(token) {
|
||||
return API_VERSION_PARAM() + (token ? '&user_token=' + token : '');
|
||||
return token ? '?user_token=' + token : '?notoken';
|
||||
}
|
||||
|
||||
export { get_json };
|
||||
@@ -34,7 +34,7 @@ export const API = {
|
||||
load_replies: async (pid, token, color_picker, cache_version) => {
|
||||
pid = parseInt(pid);
|
||||
let response = await fetch(
|
||||
API_BASE + '/api.php?action=getcomment&pid=' + pid + token_param(token),
|
||||
API_BASE + '/getcomment' + token_param(token) + '&pid=' + pid ,
|
||||
);
|
||||
let json = await handle_response(response);
|
||||
// Why delete then put ??
|
||||
@@ -61,7 +61,7 @@ export const API = {
|
||||
data.append('pid', pid);
|
||||
data.append('switch', attention ? '1' : '0');
|
||||
let response = await fetch(
|
||||
API_BASE + '/api.php?action=attention' + token_param(token),
|
||||
API_BASE + '/attention' + token_param(token),
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -81,7 +81,7 @@ export const API = {
|
||||
data.append('pid', pid);
|
||||
data.append('reason', reason);
|
||||
let response = await fetch(
|
||||
API_BASE + '/api.php?action=report' + token_param(token),
|
||||
API_BASE + '/report' + token_param(token),
|
||||
{
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@@ -95,7 +95,7 @@ export const API = {
|
||||
|
||||
get_list: async (page, token) => {
|
||||
let response = await fetch(
|
||||
API_BASE + '/api.php?action=getlist' + '&p=' + page + token_param(token),
|
||||
API_BASE + '/getlist' + token_param(token) + '&p=' + page,
|
||||
);
|
||||
return handle_response(response);
|
||||
},
|
||||
@@ -103,28 +103,28 @@ export const API = {
|
||||
get_search: async (page, keyword, token) => {
|
||||
let response = await fetch(
|
||||
API_BASE +
|
||||
'/api.php?action=search' +
|
||||
'/search' +
|
||||
token_param(token) +
|
||||
'&pagesize=' +
|
||||
SEARCH_PAGESIZE +
|
||||
'&page=' +
|
||||
page +
|
||||
'&keywords=' +
|
||||
encodeURIComponent(keyword) +
|
||||
token_param(token),
|
||||
encodeURIComponent(keyword)
|
||||
);
|
||||
return handle_response(response);
|
||||
},
|
||||
|
||||
get_single: async (pid, token) => {
|
||||
let response = await fetch(
|
||||
API_BASE + '/api.php?action=getone' + '&pid=' + pid + token_param(token),
|
||||
API_BASE + '/getone' + token_param(token) + '&pid=' + pid,
|
||||
);
|
||||
return handle_response(response);
|
||||
},
|
||||
|
||||
get_attention: async (token) => {
|
||||
let response = await fetch(
|
||||
API_BASE + '/api.php?action=getattention' + token_param(token),
|
||||
API_BASE + '/getattention' + token_param(token),
|
||||
);
|
||||
return handle_response(response);
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export function get_json(res) {
|
||||
if(!res.ok) throw Error(`网络错误 ${res.status} ${res.statusText}`);
|
||||
if(!res.ok) throw Error(`错误 ${res.status} ${res.statusText}`);
|
||||
return (
|
||||
res
|
||||
.text()
|
||||
@@ -30,6 +30,3 @@ export function listen_darkmode(override) { // override: true/false/undefined
|
||||
});
|
||||
}
|
||||
|
||||
export function API_VERSION_PARAM() {
|
||||
return '&PKUHelperAPI=3.0&jsapiver='+encodeURIComponent((process.env.REACT_APP_BUILD_INFO||'null')+'-'+(Math.floor(+new Date()/7200000)*2));
|
||||
}
|
||||
Reference in New Issue
Block a user